From 3b570edea1807a983c1265478cf9d38e42098568 Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Fri, 13 Jan 2017 09:33:02 -0500 Subject: [PATCH 001/720] 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 002/720] 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 003/720] 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 004/720] 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 005/720] 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 45b5922d015ddcb4ab5f5d75ad53e8483c3602a0 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Fri, 20 Jan 2017 19:07:20 +0100 Subject: [PATCH 006/720] dont rely on postempty, img transpose not necessary anymore --- src/backends/glvisualize.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f1e40181..08a32443 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -1141,8 +1141,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) vis = gl_bar(d, kw_args) elseif st == :image extract_extrema(d, kw_args) - z = transpose_z(series, d[:z].surf, false) - vis = GL.gl_image(z, kw_args) + vis = GL.gl_image(d[:z].surf, kw_args) elseif st == :boxplot extract_c(d, kw_args, :fill) vis = gl_boxplot(d, kw_args) @@ -1182,7 +1181,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) if _3d GLAbstraction.center!(sp_screen) end - Reactive.post_empty() + GLAbstraction.post_empty() yield() end end From bcd5d9ef9087cbf9577ce5ff4710b5e56f750045 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Sun, 22 Jan 2017 16:57:28 +0100 Subject: [PATCH 007/720] 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 008/720] 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 009/720] 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 fdadfa3a80edf3af58f818e1ae0cbd3446ecc56c Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 24 Jan 2017 02:42:20 +0100 Subject: [PATCH 010/720] small changes --- src/backends/glvisualize.jl | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 08a32443..3d48344b 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -1,4 +1,4 @@ -``#= +#= TODO * move all gl_ methods to GLPlot * integrate GLPlot UI @@ -7,7 +7,6 @@ TODO * polar plots * labes and axis * fix units in all visuals (e.g dotted lines, marker scale, surfaces) - * why is there so little unicode supported in the font!??!? =# const _glvisualize_attr = merge_with_base_supported([ @@ -134,11 +133,6 @@ function empty_screen!(screen) end nothing end -function poll_reactive() - # run_till_now blocks when message queue is empty! - Base.n_avail(Reactive._messages) > 0 && Reactive.run_till_now() -end - function get_plot_screen(list::Vector, name, result = []) for elem in list From ebf92d30332ea2e5d0ecd3eab83671e77694fc1b Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Mon, 23 Jan 2017 21:25:55 -0500 Subject: [PATCH 011/720] 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 012/720] 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 013/720] 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 014/720] 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 015/720] 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 016/720] 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 017/720] 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 018/720] 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 019/720] 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 020/720] 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 021/720] 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 From c93e2b80ca8209ef6f9704d2a91bdc9fdb971194 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 7 Feb 2017 18:28:22 -0500 Subject: [PATCH 022/720] fixes for GLVisualize --- src/backends/glvisualize.jl | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 3d48344b..f053dfb7 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -149,19 +149,20 @@ function get_plot_screen(screen, name, result = []) end function create_window(plt::Plot{GLVisualizeBackend}, visible) - name = Symbol("Plots.jl") + name = Symbol("__Plots.jl") # make sure we have any screen open if isempty(GLVisualize.get_screens()) # create a fresh, new screen parent_screen = GLVisualize.glscreen( - "Plot", + "Plots", resolution = plt[:size], visible = visible ) @async GLWindow.waiting_renderloop(parent_screen) + GLVisualize.add_screen(parent_screen) end # now lets get ourselves a permanent Plotting screen - plot_screens = get_plot_screen(GLVisualize.get_screens(), name) + plot_screens = get_plot_screen(GLVisualize.current_screen(), name) screen = if isempty(plot_screens) # no screen with `name` parent = GLVisualize.current_screen() screen = GLWindow.Screen( @@ -177,7 +178,7 @@ function create_window(plt::Plot{GLVisualizeBackend}, visible) else # okay this is silly! Lets see if we can. There is an ID we could use # will not be fine for more than 255 screens though -.-. - error("multiple Plot screens. Please don't use any screen with the name Plots.jl") + error("multiple Plot screens. Please don't use any screen with the name $name") end # Since we own this window, we can do deep cleansing empty_screen!(screen) @@ -1415,6 +1416,8 @@ function label_scatter(d, w, ho) color = get(kw, :color, nothing) kw[:color] = isa(color, Array) ? first(color) : color end + strcolor = get(kw, :stroke_color, RGBA{Float32}(0,0,0,0)) + kw[:stroke_color] = isa(strcolor, Array) ? first(strcolor) : strcolor p = get(kw, :primitive, GeometryTypes.Circle) if isa(p, GLNormalMesh) bb = GeometryTypes.AABB{Float32}(GeometryTypes.vertices(p)) @@ -1429,6 +1432,9 @@ function label_scatter(d, w, ho) kw[:scale] = Vec3f0(w/2) delete!(kw, :offset) end + if isa(p, Array) + kw[:primitive] = GeometryTypes.Circle + end GL.gl_scatter(Point2f0[(w/2, ho)], kw) end From 51a47cb2b1d231b560d8363d9ece9b510b13d3d2 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 8 Feb 2017 23:51:15 +0100 Subject: [PATCH 023/720] Added basic support for searching attributes at the console --- src/Plots.jl | 5 ++++- src/plotattr.jl | 56 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/plotattr.jl diff --git a/src/Plots.jl b/src/Plots.jl index c957ab8a..337880da 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -99,7 +99,9 @@ export center, P2, P3, - BezierCurve + BezierCurve, + + plotattr # --------------------------------------------------------- @@ -127,6 +129,7 @@ include("animation.jl") include("output.jl") include("examples.jl") include("arg_desc.jl") +include("plotattr.jl") # --------------------------------------------------------- diff --git a/src/plotattr.jl b/src/plotattr.jl new file mode 100644 index 00000000..0562a70c --- /dev/null +++ b/src/plotattr.jl @@ -0,0 +1,56 @@ + +const _attribute_defaults = Dict(:Series => Plots._series_defaults, + :Subplot => Plots._subplot_defaults, + :Plot => Plots._plot_defaults, + :Axis => Plots._axis_defaults) + +attrtypes() = join(keys(_attribute_defaults), ", ") +attributes(attrtype::Symbol) = sort(collect(keys(_attribute_defaults[attrtype]))) + +function lookup_aliases(attrtype, attribute) + attribute = Symbol(attribute) + attribute = in(attribute, keys(_keyAliases)) ? _keyAliases[attribute] : attribute + in(attribute, keys(_attribute_defaults[attrtype])) && return attribute + error("There is no attribute named $attribute in $attrtype") +end + +function plotattr() + println("Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())") +end + +function plotattr(attrtype::Symbol) + in(attrtype, keys(_attribute_defaults)) || error("Viable options are $(attrtypes())") + println("Defined $attrtype attributes are:\n$(join(attributes(attrtype), ", "))") +end + +function plotattr(attribute::AbstractString) + attribute = Symbol(attribute) + attribute = in(attribute, keys(_keyAliases)) ? _keyAliases[attribute] : attribute + for (k, v) in _attribute_defaults + if in(attribute, keys(v)) + return plotattr(k, "$attribute") + end + end + error("There is no attribute named $attribute") +end + +function plotattr(attrtype::Symbol, attribute::AbstractString) + in(attrtype, keys(_attribute_defaults)) || ArgumentError("`attrtype` must match one of $(attrtypes())") + + attribute = Symbol(lookup_aliases(attrtype, attribute)) + + desc = get(_arg_desc, attribute, "") + first_period_idx = findfirst(desc, '.') + typedesc = desc[1:first_period_idx-1] + desc = strip(desc[first_period_idx+1:end]) + als = keys(filter((_,v)->v==attribute, _keyAliases)) |> collect |> sort + als = join(map(string,als), ", ") + + + # Looks up the different elements and plots them + println("$attribute ($attrtype attribute)") + println("Aliases: $als \n") + println("Default: $(_attribute_defaults[attrtype][attribute])\t(Type: $typedesc)\n") + println("Description: ") + println(desc) +end From 82161e60bcd8c5ea9726e9bf59ab69c2eb6ed4da Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 9 Feb 2017 00:12:16 +0100 Subject: [PATCH 024/720] removed unnecessary Plots qualifier --- src/plotattr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plotattr.jl b/src/plotattr.jl index 0562a70c..4272990d 100644 --- a/src/plotattr.jl +++ b/src/plotattr.jl @@ -1,8 +1,8 @@ -const _attribute_defaults = Dict(:Series => Plots._series_defaults, - :Subplot => Plots._subplot_defaults, - :Plot => Plots._plot_defaults, - :Axis => Plots._axis_defaults) +const _attribute_defaults = Dict(:Series => _series_defaults, + :Subplot => _subplot_defaults, + :Plot => _plot_defaults, + :Axis => _axis_defaults) attrtypes() = join(keys(_attribute_defaults), ", ") attributes(attrtype::Symbol) = sort(collect(keys(_attribute_defaults[attrtype]))) From 35a56962fc2d087a4caabda90568821155d4fd1e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 9 Feb 2017 10:40:08 +0100 Subject: [PATCH 025/720] more concise output --- src/plotattr.jl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plotattr.jl b/src/plotattr.jl index 4272990d..b815adef 100644 --- a/src/plotattr.jl +++ b/src/plotattr.jl @@ -45,12 +45,12 @@ function plotattr(attrtype::Symbol, attribute::AbstractString) desc = strip(desc[first_period_idx+1:end]) als = keys(filter((_,v)->v==attribute, _keyAliases)) |> collect |> sort als = join(map(string,als), ", ") + def = _attribute_defaults[attrtype][attribute] # Looks up the different elements and plots them - println("$attribute ($attrtype attribute)") - println("Aliases: $als \n") - println("Default: $(_attribute_defaults[attrtype][attribute])\t(Type: $typedesc)\n") - println("Description: ") - println(desc) + println("$attribute ", typedesc == "" ? "" : "{$typedesc}") + als == "" || println("$als") + println("\n",desc) + println("$(attrtype) attribute, ", def == "" ? "" : " default: $def") end From d663267cde22d18e74fdc10d345073df83135c42 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 9 Feb 2017 11:12:46 +0100 Subject: [PATCH 026/720] improved println call --- src/plotattr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plotattr.jl b/src/plotattr.jl index b815adef..cc8d053b 100644 --- a/src/plotattr.jl +++ b/src/plotattr.jl @@ -49,8 +49,8 @@ function plotattr(attrtype::Symbol, attribute::AbstractString) # Looks up the different elements and plots them - println("$attribute ", typedesc == "" ? "" : "{$typedesc}") - als == "" || println("$als") - println("\n",desc) - println("$(attrtype) attribute, ", def == "" ? "" : " default: $def") + println("$attribute ", typedesc == "" ? "" : "{$typedesc}", "\n", + als == "" ? "" : "$als\n", + "\n$desc\n", + "$(attrtype) attribute, ", def == "" ? "" : " default: $def") end From 471b09bd6cb564c024dd5d0a99b4849299e1410f Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 10 Feb 2017 11:24:48 +0100 Subject: [PATCH 027/720] gr: added support for hexbin plots --- src/backends/gr.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b092edd7..5b4a3eb8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -33,7 +33,7 @@ const _gr_attr = merge_with_base_supported([ :arrow, ]) const _gr_seriestype = [ - :path, :scatter, + :path, :scatter, :hexbin, :heatmap, :pie, :image, :contour, :path3d, :scatter3d, :surface, :wireframe, :shape @@ -798,6 +798,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_draw_markers(series, x, y) end + elseif st == :hexbin + GR.hexbin(x, y, nbins = series[:bins]) + elseif st == :contour zmin, zmax = gr_lims(zaxis, false) clims = sp[:clims] From eb7534d319afc07782277984460fb2ea0504cb9a Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 14 Feb 2017 09:55:46 +0100 Subject: [PATCH 028/720] gr: corrected alignment of rotated axes labels --- src/backends/gr.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 5b4a3eb8..f79258ab 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -33,7 +33,7 @@ const _gr_attr = merge_with_base_supported([ :arrow, ]) const _gr_seriestype = [ - :path, :scatter, :hexbin, + :path, :scatter, :heatmap, :pie, :image, :contour, :path3d, :scatter3d, :surface, :wireframe, :shape @@ -653,6 +653,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) flip = sp[:yaxis][:flip] mirror = sp[:xaxis][:mirror] gr_set_font(sp[:xaxis][:tickfont], + halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], valign = (mirror ? :bottom : :top), color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) @@ -670,6 +671,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) mirror = sp[:yaxis][:mirror] gr_set_font(sp[:yaxis][:tickfont], halign = (mirror ? :left : :right), + valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2], color = sp[:yaxis][:foreground_color_axis], rotation = sp[:yaxis][:rotation]) for (cv, dv) in zip(yticks...) @@ -798,9 +800,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_draw_markers(series, x, y) end - elseif st == :hexbin - GR.hexbin(x, y, nbins = series[:bins]) - elseif st == :contour zmin, zmax = gr_lims(zaxis, false) clims = sp[:clims] From 5ae2044d02bc24785c999166bcefe246e165a392 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Tue, 14 Feb 2017 21:04:13 +0100 Subject: [PATCH 029/720] Fix halign for annotations in pgfplots backend PGFPlot uses inverted right and left parameters. --- src/backends/pgfplots.jl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index de4d4a6a..3a47295f 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -98,6 +98,12 @@ const _pgf_series_extrastyle = KW( :xsticks => "xcomb", ) +const _pgf_annotation_halign = KW( + :center => "", + :left => "right", + :right => "left" +) + # -------------------------------------------------------------------------------------- # takes in color,alpha, and returns color and alpha appropriate for pgf style @@ -139,12 +145,11 @@ 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, style=""" - $halign, + $(get(_pgf_annotation_halign,val.font.halign,"")), color=$cstr, draw opacity=$(convert(Float16,a)), rotate=$(val.font.rotation) """)) From 2a350df5ebe80fe40e32deed9681f30117e56889 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 21 Feb 2017 22:44:32 +0100 Subject: [PATCH 030/720] plot recipe to show color libraries --- src/recipes.jl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/recipes.jl b/src/recipes.jl index 156bda3e..7e0d4dde 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -802,3 +802,33 @@ abline!(args...; kw...) = abline!(current(), args...; kw...) seriestype --> :scatter real(cp.args[1]), imag(cp.args[1]) end + + +# -------------------------------------------------- +# Color Gradients + +@userplot ShowLibrary +@recipe function f(cl::ShowLibrary) + if !(length(cl.args) == 1 && isa(cl.args[1], Symbol)) + error("ShowLibrary takes the name of a color library as a Symbol") + end + + library = clibrary(cl.args[1]) + z = sqrt.((1:20)*(1:15)') + + seriestype := :heatmap + ticks := nothing + legend := false + + layout := length(library.lib) + + i = 0 + for grad in keys(library.lib) + @series begin + seriescolor := cgrad(grad, color_library = cl.args[1]) + title := grad + subplot := i += 1 + z + end + end +end From 4b2ce036e8642dae2c2cda622a938cfc347c199f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 21 Feb 2017 22:49:15 +0100 Subject: [PATCH 031/720] change numbers --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 7e0d4dde..fb452561 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -814,7 +814,7 @@ end end library = clibrary(cl.args[1]) - z = sqrt.((1:20)*(1:15)') + z = sqrt.((1:15)*(1:20)') seriestype := :heatmap ticks := nothing From d4b7bfbe1dab2d6705d7ce5b709848fde6f2f05f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 22 Feb 2017 11:48:37 +0100 Subject: [PATCH 032/720] Added a recipe to show a single gradient --- src/recipes.jl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index fb452561..152752a3 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -810,7 +810,7 @@ end @userplot ShowLibrary @recipe function f(cl::ShowLibrary) if !(length(cl.args) == 1 && isa(cl.args[1], Symbol)) - error("ShowLibrary takes the name of a color library as a Symbol") + error("showlibrary takes the name of a color library as a Symbol") end library = clibrary(cl.args[1]) @@ -832,3 +832,17 @@ end end end end + +@userplot ShowGradient +@recipe function f(grad::ShowGradient) + if !(length(grad.args) == 1 && isa(grad.args[1], Symbol)) + error("showgradient takes the name of a color gradient as a Symbol") + end + z = sqrt.((1:15)*(1:20)') + seriestype := :heatmap + ticks := nothing + legend := false + seriescolor := grad.args[1] + title := grad.args[1] + z +end From 28b026c9adebfbca231fc310eabb71e3c4aab7ee Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 22 Feb 2017 11:49:31 +0100 Subject: [PATCH 033/720] replaced boxes with symmetrical squares --- src/recipes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 152752a3..60f5997f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -814,7 +814,7 @@ end end library = clibrary(cl.args[1]) - z = sqrt.((1:15)*(1:20)') + z = (1:20).+(1:20)' seriestype := :heatmap ticks := nothing @@ -838,7 +838,7 @@ end if !(length(grad.args) == 1 && isa(grad.args[1], Symbol)) error("showgradient takes the name of a color gradient as a Symbol") end - z = sqrt.((1:15)*(1:20)') + z = (1:20).+(1:20)' seriestype := :heatmap ticks := nothing legend := false From b7536f129b3e3cf1876ed497c9d92dbc4098a16e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 22 Feb 2017 11:52:54 +0100 Subject: [PATCH 034/720] Revert "replaced boxes with symmetrical squares" This reverts commit 28b026c9adebfbca231fc310eabb71e3c4aab7ee. --- src/recipes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 60f5997f..152752a3 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -814,7 +814,7 @@ end end library = clibrary(cl.args[1]) - z = (1:20).+(1:20)' + z = sqrt.((1:15)*(1:20)') seriestype := :heatmap ticks := nothing @@ -838,7 +838,7 @@ end if !(length(grad.args) == 1 && isa(grad.args[1], Symbol)) error("showgradient takes the name of a color gradient as a Symbol") end - z = (1:20).+(1:20)' + z = sqrt.((1:15)*(1:20)') seriestype := :heatmap ticks := nothing legend := false From 5395b418525b753028e2c8e52d9aed18090b7e96 Mon Sep 17 00:00:00 2001 From: Leon Wabeke Date: Wed, 22 Feb 2017 15:57:41 +0200 Subject: [PATCH 035/720] Attempt to add support for clims to plotly backend Added support for clims, seems to work on heatmap, surface and contour. On surface zlims be still be set to be different from clims. --- src/backends/plotly.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index bbdd29b9..85c69105 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -31,6 +31,7 @@ const _plotly_attr = merge_with_base_supported([ :hover, :inset_subplots, :bar_width, + :clims, ]) const _plotly_seriestype = [ @@ -438,6 +439,11 @@ function plotly_series(plt::Plot, series::Series) end end + clims = sp[:clims] + if is_2tuple(clims) + d_out[:zmin], d_out[:zmax] = clims + end + # set the "type" if st in (:path, :scatter, :scattergl) d_out[:type] = st==:scattergl ? "scattergl" : "scatter" From fd947ab8872727da7128063395802a7a990e7633 Mon Sep 17 00:00:00 2001 From: Josh Day Date: Wed, 22 Feb 2017 10:40:16 -0500 Subject: [PATCH 036/720] only one, smaller gr marker --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index f79258ab..c17df76e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1017,7 +1017,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if series[:markershape] != :none - gr_draw_markers(series, xpos-[0.06,0.02], [ypos,ypos], 10, nothing) + gr_draw_markers(series, xpos - .035, ypos, 6, nothing) end if typeof(series[:label]) <: Array From 9e1d551173f8d2c967523c1a8448719ab2957d76 Mon Sep 17 00:00:00 2001 From: Leon Wabeke Date: Fri, 24 Feb 2017 12:19:20 +0200 Subject: [PATCH 037/720] Commit to address issue #681 Change to address issue #681 Untested change --- 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 6781314e..b0be7a3e 100644 --- a/src/backends/web.jl +++ b/src/backends/web.jl @@ -23,7 +23,7 @@ function open_browser_window(filename::AbstractString) @static if is_apple() return run(`open $(filename)`) end - @static if is_linux() + @static if is_linux() || is_bsd() # is_bsd() addition is as yet untested, but based on suggestion in https://github.com/JuliaPlots/Plots.jl/issues/681 return run(`xdg-open $(filename)`) end @static if is_windows() From 9472c0c5e5f0939ee33409de9369b46559900ad9 Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Fri, 24 Feb 2017 15:19:41 -0500 Subject: [PATCH 038/720] skip pyplot image test --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index ca7f5e3e..953ad8fe 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -23,7 +23,7 @@ facts("PyPlot") do @fact pyplot() --> Plots.PyPlotBackend() @fact backend() --> Plots.PyPlotBackend() - image_comparison_facts(:pyplot, skip=[25,30], eps=img_eps) + image_comparison_facts(:pyplot, skip=[6,25,30], eps=img_eps) end facts("GR") do From b0dabaafe896eaf79de0f311bbc0817f8df09e7e Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Sat, 25 Feb 2017 11:33:24 -0500 Subject: [PATCH 039/720] InspectDR: Reflect changes to support delta markers. --- src/backends/inspectdr.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 72034473..cb290d22 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -213,14 +213,10 @@ 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 = [] - plot.markers = [] #Clear old markers - plot.atext = [] #Clear old annotation - plot.apline = [] #Clear old poly lines - + plot.userannot = [] #Clear old markers/text annotation/polyline "annotation" return plot end @@ -277,7 +273,7 @@ For st in :shape: apline = InspectDR.PolylineAnnotation( x[rng], y[rng], line=line, fillcolor=fillcolor ) - push!(plot.apline, apline) + InspectDR.add(plot, apline) end end From 24c27737c1b8ff816d394efe2f06c2d7c0512c54 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 26 Feb 2017 08:32:52 +0100 Subject: [PATCH 040/720] fix uneven bins --- src/recipes.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 156bda3e..0585e488 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -410,6 +410,8 @@ function my_hist(v, bins; normed = false, weights = nothing) counts[idx] += (weights == nothing ? 1.0 : weights[i]) end + counts = isapprox(extrema(diff(edges))...) ? counts : counts ./ diff(edges) # for uneven bins, normalize to area. + # normalize by bar area? norm_denom = normed ? sum(diff(edges) .* counts) : 1.0 if norm_denom == 0 @@ -424,7 +426,8 @@ end edges, counts = my_hist(y, d[:bins], normed = d[:normalize], weights = d[:weights]) - x := edges + bar_width := diff(edges) + x := centers(edges) y := counts seriestype := :bar () From eab4cfdf2d4b4c5efe7e5daf285b0be2303da77e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 26 Feb 2017 17:23:43 +0100 Subject: [PATCH 041/720] allow color libraries to be used in PlotThemes --- src/themes.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 3429585a..feb665d6 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -2,7 +2,8 @@ function theme(s::Symbol; kw...) # reset? if s == :none || s == :default - PlotUtils._default_gradient[] = :inferno + PlotUtils.set_clibrary(:matplotlib) + PlotUtils.cgraddefaults(:inferno) default(; bg = :white, bglegend = :match, @@ -23,7 +24,8 @@ function theme(s::Symbol; kw...) # update the default gradient and other defaults thm = PlotThemes._themes[s] if thm.gradient != nothing - PlotUtils._default_gradient[] = PlotThemes.gradient_name(s) + PlotUtils.set_clibrary(:plotthemes) + PlotUtils.cgraddefaults(PlotThemes.gradient_name(s)) end default(; bg = thm.bg_secondary, From 6c51982793c48d9dc24e4757a880ec0f2dbe566e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 26 Feb 2017 20:43:04 +0100 Subject: [PATCH 042/720] fix theme default --- src/themes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes.jl b/src/themes.jl index feb665d6..442e67d0 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -25,7 +25,7 @@ function theme(s::Symbol; kw...) thm = PlotThemes._themes[s] if thm.gradient != nothing PlotUtils.set_clibrary(:plotthemes) - PlotUtils.cgraddefaults(PlotThemes.gradient_name(s)) + PlotUtils.cgraddefaults(default = PlotThemes.gradient_name(s)) end default(; bg = thm.bg_secondary, From b109025fac29835e5a37a6fe4e0581dc6355e189 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 27 Feb 2017 14:13:16 +0100 Subject: [PATCH 043/720] Fixed image bug --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c17df76e..b4622145 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -944,7 +944,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :image z = transpose_z(series, series[:z].surf, true) - h, w = size(z) + w, h = size(z) if eltype(z) <: Colors.AbstractGray grey = round(UInt8, float(z) * 255) rgba = map(c -> UInt32( 0xff000000 + Int(c)<<16 + Int(c)<<8 + Int(c) ), grey) From 5465479e5772b60d4a19c6eae191f9fa3908b498 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 27 Feb 2017 21:47:12 +0100 Subject: [PATCH 044/720] Put themes in Plots library --- src/themes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 442e67d0..70ee50db 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -2,7 +2,7 @@ function theme(s::Symbol; kw...) # reset? if s == :none || s == :default - PlotUtils.set_clibrary(:matplotlib) + PlotUtils.set_clibrary(:Plots) PlotUtils.cgraddefaults(:inferno) default(; bg = :white, @@ -24,7 +24,7 @@ function theme(s::Symbol; kw...) # update the default gradient and other defaults thm = PlotThemes._themes[s] if thm.gradient != nothing - PlotUtils.set_clibrary(:plotthemes) + PlotUtils.set_clibrary(:Plots) PlotUtils.cgraddefaults(default = PlotThemes.gradient_name(s)) end default(; From 6b94bbac2d9031dd41b711794855b29f82ef16af Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 27 Feb 2017 21:52:22 +0100 Subject: [PATCH 045/720] updated function names --- src/themes.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 70ee50db..c069a251 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -2,8 +2,8 @@ function theme(s::Symbol; kw...) # reset? if s == :none || s == :default - PlotUtils.set_clibrary(:Plots) - PlotUtils.cgraddefaults(:inferno) + PlotUtils.clibrary(:Plots) + PlotUtils.default_cgrad(:inferno) default(; bg = :white, bglegend = :match, @@ -24,8 +24,8 @@ function theme(s::Symbol; kw...) # update the default gradient and other defaults thm = PlotThemes._themes[s] if thm.gradient != nothing - PlotUtils.set_clibrary(:Plots) - PlotUtils.cgraddefaults(default = PlotThemes.gradient_name(s)) + PlotUtils.clibrary(:Plots) + PlotUtils.default_cgrad(default = PlotThemes.gradient_name(s)) end default(; bg = thm.bg_secondary, From cad96e652f1634acbc52f768666bf1275864327c Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 27 Feb 2017 22:45:14 +0100 Subject: [PATCH 046/720] fix error on gr --- src/recipes.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index c4bf60c4..d30b763f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -816,7 +816,7 @@ end error("showlibrary takes the name of a color library as a Symbol") end - library = clibrary(cl.args[1]) + library = PlotUtils.color_libraries[cl.args[1]] z = sqrt.((1:15)*(1:20)') seriestype := :heatmap @@ -828,8 +828,8 @@ end i = 0 for grad in keys(library.lib) @series begin - seriescolor := cgrad(grad, color_library = cl.args[1]) - title := grad + seriescolor := cgrad(grad, cl.args[1]) + title := string(grad) subplot := i += 1 z end From 41e56b1f2e4350ca9676995e18cde0d6e6d3e710 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 28 Feb 2017 07:56:00 +0100 Subject: [PATCH 047/720] put PlotThemes in :misc --- src/themes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes.jl b/src/themes.jl index c069a251..702574e2 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -24,7 +24,7 @@ function theme(s::Symbol; kw...) # update the default gradient and other defaults thm = PlotThemes._themes[s] if thm.gradient != nothing - PlotUtils.clibrary(:Plots) + PlotUtils.clibrary(:hisc) PlotUtils.default_cgrad(default = PlotThemes.gradient_name(s)) end default(; From 7aca2b1584503c28dd9660d15f13630d9b690ef3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 28 Feb 2017 09:15:32 +0100 Subject: [PATCH 048/720] fix set_axis_bgcolor --- 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 68f45be9..e1003958 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1075,7 +1075,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) py_add_legend(plt, sp, ax) # this sets the bg color inside the grid - ax[:set_axis_bgcolor](py_color(sp[:background_color_inside])) + ax[:set_facecolor](py_color(sp[:background_color_inside])) end py_drawfig(fig) end From 1b468ba5d80348b232b3542d1a8837ab9e98a924 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 28 Feb 2017 12:35:08 +0100 Subject: [PATCH 049/720] fix gr.text on showgradient --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index d30b763f..1089ea10 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -846,6 +846,6 @@ end ticks := nothing legend := false seriescolor := grad.args[1] - title := grad.args[1] + title := string(grad.args[1]) z end From 6f8881b610d3908e5413e4abc5101e2b8ed5009f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 28 Feb 2017 12:43:06 +0100 Subject: [PATCH 050/720] set defaults to sequential --- src/themes.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 702574e2..e7a39d02 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -3,7 +3,7 @@ function theme(s::Symbol; kw...) # reset? if s == :none || s == :default PlotUtils.clibrary(:Plots) - PlotUtils.default_cgrad(:inferno) + PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) default(; bg = :white, bglegend = :match, @@ -24,8 +24,8 @@ function theme(s::Symbol; kw...) # update the default gradient and other defaults thm = PlotThemes._themes[s] if thm.gradient != nothing - PlotUtils.clibrary(:hisc) - PlotUtils.default_cgrad(default = PlotThemes.gradient_name(s)) + PlotUtils.clibrary(:misc) + PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) end default(; bg = thm.bg_secondary, From 7e41a2f40d6aeff6f086faa510f2e48308d1ec18 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 1 Mar 2017 22:18:34 +0100 Subject: [PATCH 051/720] sort colors --- src/recipes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 1089ea10..3fa7a46e 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -823,10 +823,10 @@ end ticks := nothing legend := false - layout := length(library.lib) + layout --> length(library.lib) i = 0 - for grad in keys(library.lib) + for grad in sort(collect(keys(library.lib))) @series begin seriescolor := cgrad(grad, cl.args[1]) title := string(grad) From 37e2c18c3c01efe448720e49817c06e1afb008a6 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 3 Mar 2017 12:15:23 +0100 Subject: [PATCH 052/720] define default behaviour for symbol in gr_text --- src/backends/gr.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b4622145..27a0e2e3 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -172,6 +172,8 @@ function gr_polyline(x, y, func = GR.polyline; arrowside=:none) end end +gr_inqtext(x, y, s::Symbol) = gr_inqtext(x, y, string(s)) + function gr_inqtext(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.inqtextext(x, y, s[2:end-1]) @@ -182,6 +184,8 @@ function gr_inqtext(x, y, s) end end +gr_text(x, y, s::Symbol) = gr_text(x, y, string(s)) + function gr_text(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.mathtex(x, y, s[2:end-1]) From 5435ce20a935f4236ec8b2a31ebf6d7e690fe97e Mon Sep 17 00:00:00 2001 From: Andy Nowacki Date: Mon, 6 Mar 2017 10:25:21 +0000 Subject: [PATCH 053/720] Remove import of Base.scale(!); fixes #687 Base.scale and Base.scale! were deprecated in v0.5 and removed in v0.6-pre.alpha. Removing their import permits use on v0.6- and is fine since we REQUIRE v0.5 and above. --- src/components.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components.jl b/src/components.jl index bbb2f9c2..f660a149 100644 --- a/src/components.jl +++ b/src/components.jl @@ -174,7 +174,7 @@ function center(shape::Shape) Cx / 6A, Cy / 6A end -function Base.scale!(shape::Shape, x::Real, y::Real = x, c = center(shape)) +function scale!(shape::Shape, x::Real, y::Real = x, c = center(shape)) sx, sy = coords(shape) cx, cy = c for i=1:length(sx) @@ -184,7 +184,7 @@ function Base.scale!(shape::Shape, x::Real, y::Real = x, c = center(shape)) shape end -function Base.scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) +function scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) shapecopy = deepcopy(shape) scale!(shapecopy, x, y, c) end From f2235abf08cca48209954c7378075e55efd3f7f2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 6 Mar 2017 23:52:59 +0100 Subject: [PATCH 054/720] Added logic to choose *round* DateTime tick positions --- src/axes.jl | 7 +++++++ src/recipes.jl | 7 +++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index b9840e7a..dd36f824 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -156,6 +156,13 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) scale = axis[:scale] sf = scalefunc(scale) + # If the axis input was a Date or DateTime use a special logic to find + # "round" Date(Time)s as ticks + # TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime + if axis[:formatter] in (dateformatter, datetimeformatter) && scale == :identity + return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4) + end + # get a list of well-laid-out ticks scaled_ticks = if ticks == nothing optimize_ticks( diff --git a/src/recipes.jl b/src/recipes.jl index 3fa7a46e..a4f576a3 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -792,8 +792,11 @@ abline!(args...; kw...) = abline!(current(), args...; kw...) # ------------------------------------------------- # Dates -@recipe f(::Type{Date}, dt::Date) = (dt -> convert(Int,dt), dt -> string(convert(Date,dt))) -@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> convert(Int,dt), dt -> string(convert(DateTime,dt))) +dateformatter(dt) = string(convert(Date, convert(DateTime, dt))) +datetimeformatter(dt) = string(convert(DateTime, dt)) + +@recipe f(::Type{Date}, dt::Date) = (dt -> convert(Int, convert(DateTime, dt)), dateformatter) +@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> convert(Int,dt), datetimeformatter) # ------------------------------------------------- # Complex Numbers From 7a0e03b3746ce8207d5572001a0b96b4d8a8e64e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 7 Mar 2017 08:04:15 +0100 Subject: [PATCH 055/720] set dotted grid lines for pyplot --- 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 e1003958..cdc44fb1 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1059,7 +1059,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end if sp[:grid] fgcolor = py_color(sp[:foreground_color_grid]) - pyaxis[:grid](true, color = fgcolor) + pyaxis[:grid](true, color = fgcolor, linestyle = ":") ax[:set_axisbelow](true) end py_set_axis_colors(ax, axis) From fb2e12089f67a53fc92a70a3b53ee5f265a1006d Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 10 Mar 2017 23:53:00 +0100 Subject: [PATCH 056/720] remove density from like_histogram --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 8f82fec0..0ede66a9 100644 --- a/src/args.jl +++ b/src/args.jl @@ -77,7 +77,7 @@ const _typeAliases = Dict{Symbol,Symbol}( add_non_underscore_aliases!(_typeAliases) -like_histogram(seriestype::Symbol) = seriestype in (:histogram, :density) +like_histogram(seriestype::Symbol) = seriestype == :histogram like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :steppost) like_surface(seriestype::Symbol) = seriestype in (:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image) From 76e1f4720bad7d956dfd076311430f244dd96990 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 13 Mar 2017 16:05:30 +0100 Subject: [PATCH 057/720] avoid ignoring ticks set by the user --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index dd36f824..d3893330 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -159,7 +159,7 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) # If the axis input was a Date or DateTime use a special logic to find # "round" Date(Time)s as ticks # TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime - if axis[:formatter] in (dateformatter, datetimeformatter) && scale == :identity + if axis[:formatter] in (dateformatter, datetimeformatter) && ticks == nothing && scale == :identity return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4) end From ed102269e7eaa5e46ffdd74b09a92739d736a95b Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 14 Mar 2017 22:47:43 +0100 Subject: [PATCH 058/720] fix error on marker_z --- src/backends/plotly.jl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 85c69105..e19759d2 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -409,6 +409,13 @@ plotly_surface_data(series::Series, a::AbstractVector) = a plotly_surface_data(series::Series, a::AbstractMatrix) = transpose_z(series, a, false) plotly_surface_data(series::Series, a::Surface) = plotly_surface_data(series, a.surf) +#ensures that a gradient is called if a single color is supplied where a gradient is needed (e.g. if a series recipe defines marker_z) +as_gradient(grad::ColorGradient, α) = grad +as_gradient(grad, α) = cgrad(alpha = α) + +# allows passing a ColorGradient where a single color is expected - the other backends allow this +PlotUtils.rgba_string(cg::ColorGradient) = rgba_string(cg[1]) + # get a dictionary representing the series params (d is the Plots-dict, d_out is the Plotly-dict) function plotly_series(plt::Plot, series::Series) st = series[:seriestype] @@ -539,9 +546,10 @@ function plotly_series(plt::Plot, series::Series) rgba_string(series[:markercolor]) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) - grad = series[:markercolor] + grad = as_gradient(series[:markercolor], series[:markeralpha]) zmin, zmax = extrema(series[:marker_z]) - [rgba_string(grad[(zi - zmin) / (zmax - zmin)]) for zi in series[:marker_z]] + zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) + [rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]] end end From 57316484798535b747fceb0bb0695587b2b15df3 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Sat, 25 Mar 2017 17:51:33 -0400 Subject: [PATCH 059/720] Layout fix: Update plot.bb in _update_plot_object. --- src/backends/inspectdr.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index cb290d22..c58ef884 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -411,8 +411,6 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) plot = sp.o _initialize_subplot(plt, sp) _inspectdr_setupsubplot(sp) - graphbb = _inspectdr_to_pixels(plotarea(sp)) - plot.plotbb = InspectDR.plotbounds(plot.layout, graphbb) # add the annotations for ann in sp[:annotations] @@ -467,7 +465,11 @@ function _update_plot_object(plt::Plot{InspectDRBackend}) mplot = _inspectdr_getmplot(plt.o) if nothing == mplot; return; end - #TODO: should plotbb be computed here?? + for (i, sp) in enumerate(plt.subplots) + graphbb = _inspectdr_to_pixels(plotarea(sp)) + plot = mplot.subplots[i] + plot.plotbb = InspectDR.plotbounds(plot.layout, graphbb) + end gplot = _inspectdr_getgui(plt.o) if nothing == gplot; return; end From 06fd894f7945fe5f0e8200800522cef9ff36b5fb Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Mon, 27 Mar 2017 10:04:30 -0400 Subject: [PATCH 060/720] Initial implementation for HDF5 plots. --- src/backends.jl | 1 + src/backends/hdf5.jl | 498 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 499 insertions(+) create mode 100644 src/backends/hdf5.jl diff --git a/src/backends.jl b/src/backends.jl index 779b91cc..5458a6c0 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -277,6 +277,7 @@ end @init_backend GLVisualize @init_backend PGFPlots @init_backend InspectDR +@init_backend HDF5 # --------------------------------------------------------- diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl new file mode 100644 index 00000000..c7c8a126 --- /dev/null +++ b/src/backends/hdf5.jl @@ -0,0 +1,498 @@ +#HDF5 Plots: Save/replay plots to/from HDF5 +#------------------------------------------------------------------------------- + +#==Usage +=============================================================================== +Write to .hdf5 file using: + p = plot(...) + Plots.hdf5plot_write(p, "plotsave.hdf5") + +Read from .hdf5 file using: + pyplot() #Must first select backend + pread = Plots.hdf5plot_read("plotsave.hdf5") + display(pread) +==# + + +#==TODO +=============================================================================== + 1. Support more features + - SeriesAnnotations & GridLayout known to be missing. + 3. Improve error handling. + - Will likely crash if file format is off. + 2. Save data in a folder parallel to "plot". + - Will make it easier for users to locate data. + - Use HDF5 reference to link data? + 3. Develop an actual versioned file format. + - Should have some form of backward compatibility. + - Should be reliable for archival purposes. +==# + + +import FixedPointNumbers: N0f8 #In core Julia +immutable HDF5PlotNative; end #Dispatch type + + +#==Useful constants +===============================================================================# +const _hdf5_plotroot = "plot" +const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (easier to locate)? +const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type +const _hdf5plot_countid = "COUNT" #Attribute for storing count + +#Possible element types of high-level data types: +const HDF5PLOT_MAP_STR2TELEM = Dict{String, DataType}( + "NATIVE" => HDF5PlotNative, + "VOID" => Void, + "BOOL" => Bool, + "SYMBOL" => Symbol, + "TUPLE" => Tuple, + "RGBA" => ARGB{N0f8}, + "EXTREMA" => Extrema, + "LENGTH" => Length, + + #Sub-structure types: + "FONT" => Font, + "AXIS" => Axis, +) +const HDF5PLOT_MAP_TELEM2STR = Dict{DataType, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM) + + +#== +===============================================================================# + +const _hdf5_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, + :fillrange, :fillcolor, :fillalpha, + :bins, :bar_width, :bar_edges, :bar_position, + :title, :title_location, :titlefont, + :window_title, + :guide, :lims, :ticks, :scale, :flip, :rotation, + :tickfont, :guidefont, :legendfont, + :grid, :legend, :colorbar, + :marker_z, :line_z, :fill_z, + :levels, + :ribbon, :quiver, :arrow, + :orientation, + :overwrite_figure, + :polar, + :normalize, :weights, + :contours, :aspect_ratio, + :match_dimensions, + :clims, + :inset_subplots, + :dpi, + :colorbar_title, + ]) +const _hdf5_seriestype = [ + :path, :steppre, :steppost, :shape, + :scatter, :hexbin, #:histogram2d, :histogram, + # :bar, + :heatmap, :pie, :image, + :contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe + ] +const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot] +const _hdf5_marker = vcat(_allMarkers, :pixel) +const _hdf5_scale = [:identity, :ln, :log2, :log10] +is_marker_supported(::HDF5Backend, shape::Shape) = true + +function add_backend_string(::HDF5Backend) + """ + if !Plots.is_installed("HDF5") + Pkg.add("HDF5") + end + """ +end + + +#==Helper functions +===============================================================================# + +_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath" +_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath" +_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k] +_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]] + +function _hdf5_merge!(dest::Dict, src::Dict) + for (k, v) in src + if isa(v, Axis) + _hdf5_merge!(dest[k].d, v.d) + else + dest[k] = v + end + end + return +end + + +#== +===============================================================================# + +function _initialize_backend(::HDF5Backend) + @eval begin + import HDF5 + export HDF5 + end +end + +# --------------------------------------------------------------------------- + +# Create the window/figure for this backend. +function _create_backend_figure(plt::Plot{HDF5Backend}) + #Do nothing +end + +# --------------------------------------------------------------------------- + +# # this is called early in the pipeline, use it to make the plot current or something +# function _prepare_plot_object(plt::Plot{HDF5Backend}) +# end + +# --------------------------------------------------------------------------- + +# Set up the subplot within the backend object. +function _initialize_subplot(plt::Plot{HDF5Backend}, sp::Subplot{HDF5Backend}) + #Do nothing +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{HDF5Backend}, series::Series) + #Do nothing +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{HDF5Backend}, series::Series) + #Do nothing +end + +# --------------------------------------------------------------------------- + +# called just before updating layout bounding boxes... in case you need to prep +# for the calcs +function _before_layout_calcs(plt::Plot{HDF5Backend}) + #Do nothing +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{HDF5Backend}) + #Do nothing +end + +# ---------------------------------------------------------------- + +# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations]) +function _update_plot_object(plt::Plot{HDF5Backend}) + #Do nothing +end + +# ---------------------------------------------------------------- + +_show(io::IO, mime::MIME"text/plain", plt::Plot{HDF5Backend}) = nothing #Don't show + +# ---------------------------------------------------------------- + +# Display/show the plot (open a GUI window, or browser page, for example). +function _display(plt::Plot{HDF5Backend}) + msg = "HDF5 interface does not support `display()` function." + msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead." + warn(msg) + return +end + + +#==HDF5 write functions +===============================================================================# + +function _hdf5plot_writetype(grp, k::String, tstr::Array{String}) + d = HDF5.d_open(grp, k) + HDF5.a_write(d, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype(grp, k::String, T::Type) + tstr = HDF5PLOT_MAP_TELEM2STR[T] + d = HDF5.d_open(grp, k) + HDF5.a_write(d, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype(grp, T::Type) #Write directly to group + tstr = HDF5PLOT_MAP_TELEM2STR[T] + HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writecount(grp, n::Int) #Write directly to group + HDF5.a_write(grp, _hdf5plot_countid, n) +end +function _hdf5plot_gwritefields(grp, k::String, v) + grp = HDF5.g_create(grp, k) + for _k in fieldnames(v) + _v = getfield(v, _k) + kstr = string(_k) + _hdf5plot_gwrite(grp, kstr, _v) + end + _hdf5plot_writetype(grp, typeof(v)) + return +end + +# Write data +# ---------------------------------------------------------------- + +function _hdf5plot_gwrite(grp, k::String, v) #Default + grp[k] = v + _hdf5plot_writetype(grp, k, HDF5PlotNative) +end +function _hdf5plot_gwrite(grp, k::String, v::Array{Any}) +# @show grp, k +# warn("Cannot write Array: $k=$v") +end +function _hdf5plot_gwrite(grp, k::String, v::Void) + grp[k] = 0 + _hdf5plot_writetype(grp, k, Void) +end +function _hdf5plot_gwrite(grp, k::String, v::Bool) + grp[k] = Int(v) + _hdf5plot_writetype(grp, k, Bool) +end +function _hdf5plot_gwrite(grp, k::String, v::Symbol) + grp[k] = string(v) + _hdf5plot_writetype(grp, k, Symbol) +end +function _hdf5plot_gwrite(grp, k::String, v::Tuple) + varr = [v...] + if isleaftype(eltype(varr)) + grp[k] = [v...] + _hdf5plot_writetype(grp, k, Tuple) + else + warn("Cannot write tuple: $k=$v") + end +end +function _hdf5plot_gwrite(grp, k::String, d::Dict) +# warn("Cannot write dict: $k=$d") +end +function _hdf5plot_gwrite(grp, k::String, v::Range) + _hdf5plot_gwrite(grp, k, collect(v)) #For now +end +function _hdf5plot_gwrite(grp, k::String, v::ARGB{N0f8}) + grp[k] = [v.r.i, v.g.i, v.b.i, v.alpha.i] + _hdf5plot_writetype(grp, k, ARGB{N0f8}) +end +function _hdf5plot_gwrite(grp, k::String, v::Colorant) + _hdf5plot_gwrite(grp, k, ARGB{N0f8}(v)) +end +function _hdf5plot_gwrite{T<:Colorant}(grp, k::String, v::Vector{T}) + #TODO +end +function _hdf5plot_gwrite(grp, k::String, v::Extrema) + grp[k] = [v.emin, v.emax] + _hdf5plot_writetype(grp, k, Extrema) +end +function _hdf5plot_gwrite{T}(grp, k::String, v::Length{T}) + grp[k] = v.value + _hdf5plot_writetype(grp, k, [HDF5PLOT_MAP_TELEM2STR[Length], string(T)]) +end + +# Write more complex structures: +# ---------------------------------------------------------------- + +function _hdf5plot_gwrite(grp, k::String, v::Union{Plot,Subplot}) +# @show :PLOTREF, k + #Don't write plot references +end +function _hdf5plot_gwrite(grp, k::String, v::Font) + _hdf5plot_gwritefields(grp, k, v) + return +end +function _hdf5plot_gwrite(grp, k::String, v::Axis) + grp = HDF5.g_create(grp, k) + for (_k, _v) in v.d + kstr = string(_k) + _hdf5plot_gwrite(grp, kstr, _v) + end + _hdf5plot_writetype(grp, Axis) + return +end + +function _hdf5plot_write(grp, d::Dict) + for (k, v) in d + kstr = string(k) + _hdf5plot_gwrite(grp, kstr, v) + end + return +end + +# Write main plot structures: +# ---------------------------------------------------------------- + +function _hdf5plot_write(sp::Subplot{HDF5Backend}, subpath::String, f) + f = f::HDF5.HDF5File #Assert + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/attr")) + _hdf5plot_write(grp, sp.attr) + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list")) + _hdf5plot_writecount(grp, length(sp.series_list)) + for (i, series) in enumerate(sp.series_list) + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list/series$i")) + _hdf5plot_write(grp, series.d) + end + + return +end + +function _hdf5plot_write(plt::Plot{HDF5Backend}, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_create(f, _hdf5_plotelempath("attr")) + _hdf5plot_write(grp, plt.attr) + + grp = HDF5.g_create(f, _hdf5_plotelempath("subplots")) + _hdf5plot_writecount(grp, length(plt.subplots)) + + for (i, sp) in enumerate(plt.subplots) + _hdf5plot_write(sp, "subplots/subplot$i", f) + end + + return +end +function hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString) + HDF5.h5open(path, "w") do file + _hdf5plot_write(plt, file) + end +end +hdf5plot_write(path::AbstractString) = hdf5plot_write(current(), path) + + +#==HDF5 playback (read) functions +===============================================================================# + +function _hdf5plot_readcount(grp) #Read directly from group + return HDF5.a_read(grp, _hdf5plot_countid) +end + +_hdf5plot_convert(T::Type{HDF5PlotNative}, v) = v +_hdf5plot_convert(T::Type{Void}, v) = nothing +_hdf5plot_convert(T::Type{Bool}, v) = (v!=0) +_hdf5plot_convert(T::Type{Symbol}, v) = Symbol(v) +_hdf5plot_convert(T::Type{Tuple}, v) = (v...) +function _hdf5plot_convert(T::Type{ARGB{N0f8}}, v) + r, g, b, a = reinterpret(N0f8, v) + return Colors.ARGB{N0f8}(r, g, b, a) +end +_hdf5plot_convert(T::Type{Extrema}, v) = Extrema(v[1], v[2]) + +# Read data structures: +# ---------------------------------------------------------------- + +function _hdf5plot_read(grp, k::String, T::Type, dtid) + v = HDF5.d_read(grp, k) + return _hdf5plot_convert(T, v) +end +function _hdf5plot_read(grp, k::String, T::Type{Length}, dtid::Vector) + v = HDF5.d_read(grp, k) + TU = Symbol(dtid[2]) + T = typeof(v) + return Length{TU,T}(v) +end + +# Read more complex data structures: +# ---------------------------------------------------------------- +function _hdf5plot_read(grp, k::String, T::Type{Font}, dtid) + grp = HDF5.g_open(grp, k) + + family = _hdf5plot_read(grp, "family") + pointsize = _hdf5plot_read(grp, "pointsize") + halign = _hdf5plot_read(grp, "halign") + valign = _hdf5plot_read(grp, "valign") + rotation = _hdf5plot_read(grp, "rotation") + color = _hdf5plot_read(grp, "color") + return Font(family, pointsize, halign, valign, rotation, color) +end +function _hdf5plot_read(grp, k::String, T::Type{Axis}, dtid) + grp = HDF5.g_open(grp, k) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + return Axis([], kwlist) +end + +function _hdf5plot_read(grp, k::String) + dtid = HDF5.a_read(grp[k], _hdf5plot_datatypeid) + T = _hdf5_map_str2telem(dtid) #expect exception + return _hdf5plot_read(grp, k, T, dtid) +end + +#Read in values in group to populate d: +function _hdf5plot_read(grp, d::Dict) + gnames = names(grp) + for k in gnames + try + v = _hdf5plot_read(grp, k) + d[Symbol(k)] = v + catch + warn(k) + end + end + return +end + +# Read main plot structures: +# ---------------------------------------------------------------- + +function _hdf5plot_read(sp::Subplot, subpath::String, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/attr")) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + _hdf5_merge!(sp.attr, kwlist) + + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list")) + nseries = _hdf5plot_readcount(grp) + + for i in 1:nseries + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list/series$i")) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + plot!(sp, kwlist[:x], kwlist[:y]) #Add data & create data structures + _hdf5_merge!(sp.series_list[end].d, kwlist) + end + + return +end + +function _hdf5plot_read(plt::Plot, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_open(f, _hdf5_plotelempath("attr")) + _hdf5plot_read(grp, plt.attr) + + for (i, sp) in enumerate(plt.subplots) + _hdf5plot_read(sp, "subplots/subplot$i", f) + end + + return +end + +function hdf5plot_read(path::AbstractString) + plt = nothing + HDF5.h5open(path, "r") do file + grp = HDF5.g_open(file, _hdf5_plotelempath("subplots")) + n = _hdf5plot_readcount(grp) + plt = plot(layout=n) #Get reference to a new plot + _hdf5plot_read(plt, file) + end + return plt +end + +#Last line From 034a1af649ca29efb1d293b85de7c711c629f421 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 29 Mar 2017 23:20:30 +0200 Subject: [PATCH 061/720] restore bar_width behavior for date x axis --- src/axes.jl | 21 +++++++++++++++++++-- src/recipes.jl | 6 +++--- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index d3893330..7af2d7c5 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -158,9 +158,26 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) # If the axis input was a Date or DateTime use a special logic to find # "round" Date(Time)s as ticks + # This bypasses the rest of optimal_ticks_and_labels, because + # optimize_datetime_ticks returns ticks AND labels: the label format (Date + # or DateTime) is chosen based on the time span between amin and amax + # rather than on the input format # TODO: maybe: non-trivial scale (:ln, :log2, :log10) for date/datetime - if axis[:formatter] in (dateformatter, datetimeformatter) && ticks == nothing && scale == :identity - return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4) + if ticks == nothing && scale == :identity + if axis[:formatter] == dateformatter + # optimize_datetime_ticks returns ticks and labels(!) based on + # integers/floats corresponding to the DateTime type. Thus, the axes + # limits, which resulted from converting the Date type to integers, + # are converted to 'DateTime integers' (actually floats) before + # being passed to optimize_datetime_ticks. + # (convert(Int, convert(DateTime, convert(Date, i))) == 87600000*i) + ticks, labels = optimize_datetime_ticks(864e5 * amin, 864e5 * amax; + k_min = 2, k_max = 4) + # Now the ticks are converted back to floats corresponding to Dates. + return ticks / 864e5, labels + elseif axis[:formatter] == datetimeformatter + return optimize_datetime_ticks(amin, amax; k_min = 2, k_max = 4) + end end # get a list of well-laid-out ticks diff --git a/src/recipes.jl b/src/recipes.jl index a4f576a3..3f63ea40 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -792,11 +792,11 @@ abline!(args...; kw...) = abline!(current(), args...; kw...) # ------------------------------------------------- # Dates -dateformatter(dt) = string(convert(Date, convert(DateTime, dt))) +dateformatter(dt) = string(convert(Date, dt)) datetimeformatter(dt) = string(convert(DateTime, dt)) -@recipe f(::Type{Date}, dt::Date) = (dt -> convert(Int, convert(DateTime, dt)), dateformatter) -@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> convert(Int,dt), datetimeformatter) +@recipe f(::Type{Date}, dt::Date) = (dt -> convert(Int, dt), dateformatter) +@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> convert(Int, dt), datetimeformatter) # ------------------------------------------------- # Complex Numbers From ffb9878893b75378f710fc5511c7e5518a0b9cdf Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 31 Mar 2017 16:26:29 +0200 Subject: [PATCH 062/720] gr: use correct colorbar() routine --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b4622145..fc8d2700 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -421,7 +421,7 @@ end function gr_colorbar(sp::Subplot) if sp[:colorbar] != :none gr_set_viewport_cmap(sp) - GR.colormap() + GR.colorbar() gr_set_viewport_plotarea() end end From b4846bd5d55202bb6948fb3979f69705d2ef552f Mon Sep 17 00:00:00 2001 From: Michael Cawte Date: Thu, 6 Apr 2017 11:58:50 +1200 Subject: [PATCH 063/720] Added an animation with subplots example --- src/examples.jl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/examples.jl b/src/examples.jl index 96872851..9f54509d 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -172,6 +172,24 @@ PlotExample("", end)] ), +PlotExample("Animation with subplots", + "The `layout` macro can be used to create an animation with subplots.", + [:(begin + l = @layout([[a; b] c]) + p = plot(plot([sin,cos],1,leg=false), + scatter([atan,cos],1,leg=false), + plot(log,1,xlims=(1,10π),ylims=(0,5),leg=false),layout=l) + + anim = Animation() + for x = linspace(1,10π,100) + plot(push!(p,x,Float64[sin(x),cos(x),atan(x),cos(x),log(x)])) + frame(anim) + end + end)] +), + + + PlotExample("Open/High/Low/Close", "Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y` argument. This uses recipes to first convert the tuples to OHLC objects, and subsequently create a :path series with the appropriate line segments.", [:(begin From 2d69fc39de7522770a53d9a9078314c8cebad37a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sat, 8 Apr 2017 13:14:41 +0200 Subject: [PATCH 064/720] add vectorfield alias to quiver --- src/args.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 0ede66a9..fa5a8e2f 100644 --- a/src/args.jl +++ b/src/args.jl @@ -65,6 +65,7 @@ const _typeAliases = Dict{Symbol,Symbol}( :polygon => :shape, :box => :boxplot, :velocity => :quiver, + :vectorfield => :quiver, :gradient => :quiver, :img => :image, :imshow => :image, @@ -445,7 +446,7 @@ add_aliases(:color_palette, :palette) add_aliases(:overwrite_figure, :clf, :clearfig, :overwrite, :reuse) add_aliases(:xerror, :xerr, :xerrorbar) add_aliases(:yerror, :yerr, :yerrorbar, :err, :errorbar) -add_aliases(:quiver, :velocity, :quiver2d, :gradient) +add_aliases(:quiver, :velocity, :quiver2d, :gradient, :vectorfield) add_aliases(:normalize, :norm, :normed, :normalized) add_aliases(:aspect_ratio, :aspectratio, :axis_ratio, :axisratio, :ratio) add_aliases(:match_dimensions, :transpose, :transpose_z) From dd3f65496ad98c8a393fd0f766dd81e0288b2de4 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 10 Apr 2017 12:54:57 +0200 Subject: [PATCH 065/720] gr: use correct marker size --- src/backends/gr.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b4622145..33a41a34 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -283,7 +283,8 @@ end # draw ONE symbol marker function gr_draw_marker(xi, yi, msize::Number, shape::Symbol) GR.setmarkertype(gr_markertype[shape]) - GR.setmarkersize(0.3msize) + w, h = gr_plot_size + GR.setmarkersize(0.3msize / ((w + h) * 0.001)) GR.polymarker([xi], [yi]) end From ccb9df2a0870b9ff6307b6157f92114ac73917f6 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 10 Apr 2017 14:56:38 +0200 Subject: [PATCH 066/720] gr: use correct line width --- src/backends/gr.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0e021012..9eb16134 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -335,9 +335,10 @@ end # --------------------------------------------------------- -function gr_set_line(w, style, c) #, a) +function gr_set_line(lw, style, c) #, a) GR.setlinetype(gr_linetype[style]) - GR.setlinewidth(w) + w, h = gr_plot_size + GR.setlinewidth(max(1, lw / ((w + h) * 0.001))) gr_set_linecolor(c) #, a) end From 5d4f3182fc266347e8f529e708094cb40f91e65b Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 13 Apr 2017 10:51:03 +0200 Subject: [PATCH 067/720] gr: expand extrema for heatmap() axes --- src/backends/gr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9eb16134..24ddfd42 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -551,6 +551,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if st == :heatmap outside_ticks = true + x, y = heatmap_edges(series[:x]), heatmap_edges(series[:y]) + expand_extrema!(sp[:xaxis], x) + expand_extrema!(sp[:yaxis], y) + data_lims = gr_xy_axislims(sp) end end @@ -765,10 +769,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # recompute data if typeof(z) <: Surface - # if st == :heatmap - # expand_extrema!(sp[:xaxis], (x[1]-0.5*(x[2]-x[1]), x[end]+0.5*(x[end]-x[end-1]))) - # expand_extrema!(sp[:yaxis], (y[1]-0.5*(y[2]-y[1]), y[end]+0.5*(y[end]-y[end-1]))) - # end z = vec(transpose_z(series, z.surf, false)) elseif ispolar(sp) if frng != nothing From 066ff96b5845599d860305b374f9dee4955857d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 13 Apr 2017 19:58:31 +0200 Subject: [PATCH 068/720] Use clims with :surface for PyPlot --- src/backends/pyplot.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cdc44fb1..dcbd6461 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -683,6 +683,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end z = transpose_z(series, z) if st == :surface + clims = sp[:clims] + if is_2tuple(clims) + isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) + isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) + end 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)) From 9a1efefbd45d882f2e8f247b0183825d6dc852ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 13 Apr 2017 22:17:34 +0200 Subject: [PATCH 069/720] Update Travis badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a47da192..b88fe561 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Plots -[![Build Status](https://travis-ci.org/tbreloff/Plots.jl.svg?branch=master)](https://travis-ci.org/tbreloff/Plots.jl) +[![Build Status](https://travis-ci.org/JuliaPlots/Plots.jl.svg?branch=master)](https://travis-ci.org/JuliaPlots/Plots.jl) [![Join the chat at https://gitter.im/tbreloff/Plots.jl](https://badges.gitter.im/tbreloff/Plots.jl.svg)](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From f11828075b2a8c46cb306d8c3deadaa0ed58a03d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Thu, 13 Apr 2017 22:20:03 +0200 Subject: [PATCH 070/720] Fix #770 --- src/components.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index f660a149..551fbee8 100644 --- a/src/components.jl +++ b/src/components.jl @@ -521,7 +521,7 @@ Base.Array(surf::Surface) = surf.surf for f in (:length, :size) @eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...) end -Base.copy(surf::Surface) = Surface{typeof(surf.surf)}(copy(surf.surf)) +Base.copy(surf::Surface) = Surface(copy(surf.surf)) Base.eltype{T}(surf::Surface{T}) = eltype(T) function expand_extrema!(a::Axis, surf::Surface) From 0d665c661f23a4248d2ecb76a723e4efbbd7a592 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 15 Apr 2017 13:14:14 -0700 Subject: [PATCH 071/720] complex recipe --- src/recipes.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/recipes.jl b/src/recipes.jl index 3f63ea40..83b3a8e8 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -809,6 +809,18 @@ datetimeformatter(dt) = string(convert(DateTime, dt)) real(cp.args[1]), imag(cp.args[1]) end +# Splits a complex matrix to its real and complex parts +# Reals defaults solid, imaginary defaults dashed +# Label defaults are changed to match the real-imaginary reference / indexing +@recipe function f{T<:Number,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}) + A = real.(y) + B = imag.(y) + _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] + linestyle --> reshape([!iseven(i) ? :solid : :dash for i in 1:2size(A,2)],1,2size(A,2)) + label --> reshape([!iseven(i) ? "Re(y$(i÷2+1))" : "Im(y$(i÷2))" for i in 1:2size(A,2)],1,2size(A,2)) + x,_y +end + # -------------------------------------------------- # Color Gradients From 1852ba99b35b96c6b2a858c3744c1edcd32ed334 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 15 Apr 2017 13:16:40 -0700 Subject: [PATCH 072/720] force real x --- src/recipes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 83b3a8e8..a22dc069 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -811,8 +811,8 @@ end # Splits a complex matrix to its real and complex parts # Reals defaults solid, imaginary defaults dashed -# Label defaults are changed to match the real-imaginary reference / indexing -@recipe function f{T<:Number,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}) +# Label defaults are changed to match the real-imaginary reference / indexing +@recipe function f{T<:Real,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}) A = real.(y) B = imag.(y) _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] From 9a59df793dba43aed9104598b3d6ae591840d859 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sat, 15 Apr 2017 17:00:00 -0700 Subject: [PATCH 073/720] coloring setup --- src/recipes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/recipes.jl b/src/recipes.jl index a22dc069..984b4a0a 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -818,6 +818,7 @@ end _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] linestyle --> reshape([!iseven(i) ? :solid : :dash for i in 1:2size(A,2)],1,2size(A,2)) label --> reshape([!iseven(i) ? "Re(y$(i÷2+1))" : "Im(y$(i÷2))" for i in 1:2size(A,2)],1,2size(A,2)) + color --> reshape([!iseven(i) ? i÷2+1 : i÷2 for i in 1:2size(A,2)],1,2size(A,2)) x,_y end From 7def4e8e7372cff8b6d046d8f578635964f173a9 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sun, 16 Apr 2017 13:01:51 -0700 Subject: [PATCH 074/720] add transformation option --- src/recipes.jl | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 984b4a0a..1bef17c8 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -812,14 +812,30 @@ end # Splits a complex matrix to its real and complex parts # Reals defaults solid, imaginary defaults dashed # Label defaults are changed to match the real-imaginary reference / indexing -@recipe function f{T<:Real,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}) - A = real.(y) - B = imag.(y) - _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] - linestyle --> reshape([!iseven(i) ? :solid : :dash for i in 1:2size(A,2)],1,2size(A,2)) - label --> reshape([!iseven(i) ? "Re(y$(i÷2+1))" : "Im(y$(i÷2))" for i in 1:2size(A,2)],1,2size(A,2)) - color --> reshape([!iseven(i) ? i÷2+1 : i÷2 for i in 1:2size(A,2)],1,2size(A,2)) - x,_y +@recipe function f{T<:Real,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}; + transformation=:split2D) + if transformation==:split2D + A = real.(y) + B = imag.(y) + _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] + linestyle --> reshape([!iseven(i) ? :solid : :dash for i in 1:2size(A,2)],1,2size(A,2)) + label --> reshape([!iseven(i) ? "Re(y$(i÷2+1))" : "Im(y$(i÷2))" for i in 1:2size(A,2)],1,2size(A,2)) + color --> reshape([!iseven(i) ? i÷2+1 : i÷2 for i in 1:2size(A,2)],1,2size(A,2)) + retval = (x,_y) + elseif transformation==:split3D + A = real.(y) + B = imag.(y) + ylabel --> "Re(y)" + zlabel --> "Im(y)" + retval = (x,A,B) + elseif transformation==:modulus + _y = norm.(y) + label --> reshape(["||y$(i)||" for i in 1:size(_y,2)],1,size(_y,2)) + retval = (x,_y) + else + error("Transformation unknown. Please use :split2D, :split3D, or :modulus") + end + (retval...) end From 0be08242077129b3c40da812b793d746ac45f187 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sun, 16 Apr 2017 13:14:12 -0700 Subject: [PATCH 075/720] (complex) type recipe --- src/recipes.jl | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 1bef17c8..48c201bf 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -801,12 +801,10 @@ datetimeformatter(dt) = string(convert(DateTime, dt)) # ------------------------------------------------- # Complex Numbers -@userplot ComplexPlot -@recipe function f(cp::ComplexPlot) - xguide --> "Real Part" - yguide --> "Imaginary Part" - seriestype --> :scatter - real(cp.args[1]), imag(cp.args[1]) +@recipe function f{T<:Number}(A::Array{Complex{T}}) + xguide --> "Re(x)" + yguide --> "Im(x)" + real.(A), imag.(A) end # Splits a complex matrix to its real and complex parts From 3e7dd9bb77cd51ac432aaae5c5e7bdfb481f3566 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 17 Apr 2017 22:15:13 -0700 Subject: [PATCH 076/720] tone down recipe --- src/recipes.jl | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 48c201bf..5be5b6e0 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -810,30 +810,10 @@ end # Splits a complex matrix to its real and complex parts # Reals defaults solid, imaginary defaults dashed # Label defaults are changed to match the real-imaginary reference / indexing -@recipe function f{T<:Real,T2<:Number}(x::AbstractArray{T},y::Array{Complex{T2}}; - transformation=:split2D) - if transformation==:split2D - A = real.(y) - B = imag.(y) - _y = [!iseven(i) ? A[:,i÷2+1] : B[:,i÷2] for i in 1:2size(A,2)] - linestyle --> reshape([!iseven(i) ? :solid : :dash for i in 1:2size(A,2)],1,2size(A,2)) - label --> reshape([!iseven(i) ? "Re(y$(i÷2+1))" : "Im(y$(i÷2))" for i in 1:2size(A,2)],1,2size(A,2)) - color --> reshape([!iseven(i) ? i÷2+1 : i÷2 for i in 1:2size(A,2)],1,2size(A,2)) - retval = (x,_y) - elseif transformation==:split3D - A = real.(y) - B = imag.(y) - ylabel --> "Re(y)" - zlabel --> "Im(y)" - retval = (x,A,B) - elseif transformation==:modulus - _y = norm.(y) - label --> reshape(["||y$(i)||" for i in 1:size(_y,2)],1,size(_y,2)) - retval = (x,_y) - else - error("Transformation unknown. Please use :split2D, :split3D, or :modulus") - end - (retval...) +@recipe function f{T<:Real,T2}(x::AbstractArray{T},y::Array{Complex{T2}}) + ylabel --> "Re(y)" + zlabel --> "Im(y)" + x,real.(y),imag.(y) end From 5166d164062c93e0a0bab11829b4143c599e2c8d Mon Sep 17 00:00:00 2001 From: Jonathan Anderson Date: Tue, 18 Apr 2017 10:32:07 -0500 Subject: [PATCH 077/720] Update gr.jl inline display to match GR.jl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I wanted to switch from using GR directly to using Plots, but the inline plots were not working for me. The following change is sufficient to generate inline plots in iterm for me https://github.com/jheinen/GR.jl/blob/0f167b2be921a0014c405f760a1e1bc22b222751/src/GR.jl#L3014 julia> versioninfo() Julia Version 0.6.0-pre.beta.187 Commit 55c97fb* (2017-04-17 23:06 UTC) Platform Info: OS: Linux (x86_64-redhat-linux) CPU: Intel(R) Xeon(R) CPU E5-2670 v3 @ 2.30GHz WORD_SIZE: 64 BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Haswell) LAPACK: libopenblas64_ LIBM: libopenlibm LLVM: libLLVM-3.9.1 (ORCJIT, haswell) julia> using TerminalExtensions julia> using Plots julia> gr(display_type=:inline); julia> z=[sin(sqrt(x^2+y^2)) for x in linspace(-2π,2π,50), y in linspace(-2π,2π,50)]; julia> contour(z) --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 24ddfd42..b8e3b460 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1109,7 +1109,7 @@ function _display(plt::Plot{GRBackend}) ENV["GKS_FILEPATH"] = filepath gr_display(plt) GR.emergencyclosegks() - content = string("\033]1337;File=inline=1;preserveAspectRatio=0:", base64encode(open(readbytes, filepath)), "\a") + content = string("\033]1337;File=inline=1;preserveAspectRatio=0:", base64encode(open(read, filepath)), "\a") println(content) rm(filepath) else From ec6f75b59e8b67eef6ec04f3183cb87f609d8482 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Wed, 19 Apr 2017 16:14:48 +0200 Subject: [PATCH 078/720] Revert "Initial implementation for HDF5 plots." --- src/backends.jl | 1 - src/backends/hdf5.jl | 498 ------------------------------------------- 2 files changed, 499 deletions(-) delete mode 100644 src/backends/hdf5.jl diff --git a/src/backends.jl b/src/backends.jl index 5458a6c0..779b91cc 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -277,7 +277,6 @@ end @init_backend GLVisualize @init_backend PGFPlots @init_backend InspectDR -@init_backend HDF5 # --------------------------------------------------------- diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl deleted file mode 100644 index c7c8a126..00000000 --- a/src/backends/hdf5.jl +++ /dev/null @@ -1,498 +0,0 @@ -#HDF5 Plots: Save/replay plots to/from HDF5 -#------------------------------------------------------------------------------- - -#==Usage -=============================================================================== -Write to .hdf5 file using: - p = plot(...) - Plots.hdf5plot_write(p, "plotsave.hdf5") - -Read from .hdf5 file using: - pyplot() #Must first select backend - pread = Plots.hdf5plot_read("plotsave.hdf5") - display(pread) -==# - - -#==TODO -=============================================================================== - 1. Support more features - - SeriesAnnotations & GridLayout known to be missing. - 3. Improve error handling. - - Will likely crash if file format is off. - 2. Save data in a folder parallel to "plot". - - Will make it easier for users to locate data. - - Use HDF5 reference to link data? - 3. Develop an actual versioned file format. - - Should have some form of backward compatibility. - - Should be reliable for archival purposes. -==# - - -import FixedPointNumbers: N0f8 #In core Julia -immutable HDF5PlotNative; end #Dispatch type - - -#==Useful constants -===============================================================================# -const _hdf5_plotroot = "plot" -const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (easier to locate)? -const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type -const _hdf5plot_countid = "COUNT" #Attribute for storing count - -#Possible element types of high-level data types: -const HDF5PLOT_MAP_STR2TELEM = Dict{String, DataType}( - "NATIVE" => HDF5PlotNative, - "VOID" => Void, - "BOOL" => Bool, - "SYMBOL" => Symbol, - "TUPLE" => Tuple, - "RGBA" => ARGB{N0f8}, - "EXTREMA" => Extrema, - "LENGTH" => Length, - - #Sub-structure types: - "FONT" => Font, - "AXIS" => Axis, -) -const HDF5PLOT_MAP_TELEM2STR = Dict{DataType, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM) - - -#== -===============================================================================# - -const _hdf5_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, - :fillrange, :fillcolor, :fillalpha, - :bins, :bar_width, :bar_edges, :bar_position, - :title, :title_location, :titlefont, - :window_title, - :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, - :marker_z, :line_z, :fill_z, - :levels, - :ribbon, :quiver, :arrow, - :orientation, - :overwrite_figure, - :polar, - :normalize, :weights, - :contours, :aspect_ratio, - :match_dimensions, - :clims, - :inset_subplots, - :dpi, - :colorbar_title, - ]) -const _hdf5_seriestype = [ - :path, :steppre, :steppost, :shape, - :scatter, :hexbin, #:histogram2d, :histogram, - # :bar, - :heatmap, :pie, :image, - :contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe - ] -const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot] -const _hdf5_marker = vcat(_allMarkers, :pixel) -const _hdf5_scale = [:identity, :ln, :log2, :log10] -is_marker_supported(::HDF5Backend, shape::Shape) = true - -function add_backend_string(::HDF5Backend) - """ - if !Plots.is_installed("HDF5") - Pkg.add("HDF5") - end - """ -end - - -#==Helper functions -===============================================================================# - -_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath" -_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath" -_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k] -_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]] - -function _hdf5_merge!(dest::Dict, src::Dict) - for (k, v) in src - if isa(v, Axis) - _hdf5_merge!(dest[k].d, v.d) - else - dest[k] = v - end - end - return -end - - -#== -===============================================================================# - -function _initialize_backend(::HDF5Backend) - @eval begin - import HDF5 - export HDF5 - end -end - -# --------------------------------------------------------------------------- - -# Create the window/figure for this backend. -function _create_backend_figure(plt::Plot{HDF5Backend}) - #Do nothing -end - -# --------------------------------------------------------------------------- - -# # this is called early in the pipeline, use it to make the plot current or something -# function _prepare_plot_object(plt::Plot{HDF5Backend}) -# end - -# --------------------------------------------------------------------------- - -# Set up the subplot within the backend object. -function _initialize_subplot(plt::Plot{HDF5Backend}, sp::Subplot{HDF5Backend}) - #Do nothing -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{HDF5Backend}, series::Series) - #Do nothing -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{HDF5Backend}, series::Series) - #Do nothing -end - -# --------------------------------------------------------------------------- - -# called just before updating layout bounding boxes... in case you need to prep -# for the calcs -function _before_layout_calcs(plt::Plot{HDF5Backend}) - #Do nothing -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{HDF5Backend}) - #Do nothing -end - -# ---------------------------------------------------------------- - -# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations]) -function _update_plot_object(plt::Plot{HDF5Backend}) - #Do nothing -end - -# ---------------------------------------------------------------- - -_show(io::IO, mime::MIME"text/plain", plt::Plot{HDF5Backend}) = nothing #Don't show - -# ---------------------------------------------------------------- - -# Display/show the plot (open a GUI window, or browser page, for example). -function _display(plt::Plot{HDF5Backend}) - msg = "HDF5 interface does not support `display()` function." - msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead." - warn(msg) - return -end - - -#==HDF5 write functions -===============================================================================# - -function _hdf5plot_writetype(grp, k::String, tstr::Array{String}) - d = HDF5.d_open(grp, k) - HDF5.a_write(d, _hdf5plot_datatypeid, tstr) -end -function _hdf5plot_writetype(grp, k::String, T::Type) - tstr = HDF5PLOT_MAP_TELEM2STR[T] - d = HDF5.d_open(grp, k) - HDF5.a_write(d, _hdf5plot_datatypeid, tstr) -end -function _hdf5plot_writetype(grp, T::Type) #Write directly to group - tstr = HDF5PLOT_MAP_TELEM2STR[T] - HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) -end -function _hdf5plot_writecount(grp, n::Int) #Write directly to group - HDF5.a_write(grp, _hdf5plot_countid, n) -end -function _hdf5plot_gwritefields(grp, k::String, v) - grp = HDF5.g_create(grp, k) - for _k in fieldnames(v) - _v = getfield(v, _k) - kstr = string(_k) - _hdf5plot_gwrite(grp, kstr, _v) - end - _hdf5plot_writetype(grp, typeof(v)) - return -end - -# Write data -# ---------------------------------------------------------------- - -function _hdf5plot_gwrite(grp, k::String, v) #Default - grp[k] = v - _hdf5plot_writetype(grp, k, HDF5PlotNative) -end -function _hdf5plot_gwrite(grp, k::String, v::Array{Any}) -# @show grp, k -# warn("Cannot write Array: $k=$v") -end -function _hdf5plot_gwrite(grp, k::String, v::Void) - grp[k] = 0 - _hdf5plot_writetype(grp, k, Void) -end -function _hdf5plot_gwrite(grp, k::String, v::Bool) - grp[k] = Int(v) - _hdf5plot_writetype(grp, k, Bool) -end -function _hdf5plot_gwrite(grp, k::String, v::Symbol) - grp[k] = string(v) - _hdf5plot_writetype(grp, k, Symbol) -end -function _hdf5plot_gwrite(grp, k::String, v::Tuple) - varr = [v...] - if isleaftype(eltype(varr)) - grp[k] = [v...] - _hdf5plot_writetype(grp, k, Tuple) - else - warn("Cannot write tuple: $k=$v") - end -end -function _hdf5plot_gwrite(grp, k::String, d::Dict) -# warn("Cannot write dict: $k=$d") -end -function _hdf5plot_gwrite(grp, k::String, v::Range) - _hdf5plot_gwrite(grp, k, collect(v)) #For now -end -function _hdf5plot_gwrite(grp, k::String, v::ARGB{N0f8}) - grp[k] = [v.r.i, v.g.i, v.b.i, v.alpha.i] - _hdf5plot_writetype(grp, k, ARGB{N0f8}) -end -function _hdf5plot_gwrite(grp, k::String, v::Colorant) - _hdf5plot_gwrite(grp, k, ARGB{N0f8}(v)) -end -function _hdf5plot_gwrite{T<:Colorant}(grp, k::String, v::Vector{T}) - #TODO -end -function _hdf5plot_gwrite(grp, k::String, v::Extrema) - grp[k] = [v.emin, v.emax] - _hdf5plot_writetype(grp, k, Extrema) -end -function _hdf5plot_gwrite{T}(grp, k::String, v::Length{T}) - grp[k] = v.value - _hdf5plot_writetype(grp, k, [HDF5PLOT_MAP_TELEM2STR[Length], string(T)]) -end - -# Write more complex structures: -# ---------------------------------------------------------------- - -function _hdf5plot_gwrite(grp, k::String, v::Union{Plot,Subplot}) -# @show :PLOTREF, k - #Don't write plot references -end -function _hdf5plot_gwrite(grp, k::String, v::Font) - _hdf5plot_gwritefields(grp, k, v) - return -end -function _hdf5plot_gwrite(grp, k::String, v::Axis) - grp = HDF5.g_create(grp, k) - for (_k, _v) in v.d - kstr = string(_k) - _hdf5plot_gwrite(grp, kstr, _v) - end - _hdf5plot_writetype(grp, Axis) - return -end - -function _hdf5plot_write(grp, d::Dict) - for (k, v) in d - kstr = string(k) - _hdf5plot_gwrite(grp, kstr, v) - end - return -end - -# Write main plot structures: -# ---------------------------------------------------------------- - -function _hdf5plot_write(sp::Subplot{HDF5Backend}, subpath::String, f) - f = f::HDF5.HDF5File #Assert - grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/attr")) - _hdf5plot_write(grp, sp.attr) - grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list")) - _hdf5plot_writecount(grp, length(sp.series_list)) - for (i, series) in enumerate(sp.series_list) - grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list/series$i")) - _hdf5plot_write(grp, series.d) - end - - return -end - -function _hdf5plot_write(plt::Plot{HDF5Backend}, f) - f = f::HDF5.HDF5File #Assert - - grp = HDF5.g_create(f, _hdf5_plotelempath("attr")) - _hdf5plot_write(grp, plt.attr) - - grp = HDF5.g_create(f, _hdf5_plotelempath("subplots")) - _hdf5plot_writecount(grp, length(plt.subplots)) - - for (i, sp) in enumerate(plt.subplots) - _hdf5plot_write(sp, "subplots/subplot$i", f) - end - - return -end -function hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString) - HDF5.h5open(path, "w") do file - _hdf5plot_write(plt, file) - end -end -hdf5plot_write(path::AbstractString) = hdf5plot_write(current(), path) - - -#==HDF5 playback (read) functions -===============================================================================# - -function _hdf5plot_readcount(grp) #Read directly from group - return HDF5.a_read(grp, _hdf5plot_countid) -end - -_hdf5plot_convert(T::Type{HDF5PlotNative}, v) = v -_hdf5plot_convert(T::Type{Void}, v) = nothing -_hdf5plot_convert(T::Type{Bool}, v) = (v!=0) -_hdf5plot_convert(T::Type{Symbol}, v) = Symbol(v) -_hdf5plot_convert(T::Type{Tuple}, v) = (v...) -function _hdf5plot_convert(T::Type{ARGB{N0f8}}, v) - r, g, b, a = reinterpret(N0f8, v) - return Colors.ARGB{N0f8}(r, g, b, a) -end -_hdf5plot_convert(T::Type{Extrema}, v) = Extrema(v[1], v[2]) - -# Read data structures: -# ---------------------------------------------------------------- - -function _hdf5plot_read(grp, k::String, T::Type, dtid) - v = HDF5.d_read(grp, k) - return _hdf5plot_convert(T, v) -end -function _hdf5plot_read(grp, k::String, T::Type{Length}, dtid::Vector) - v = HDF5.d_read(grp, k) - TU = Symbol(dtid[2]) - T = typeof(v) - return Length{TU,T}(v) -end - -# Read more complex data structures: -# ---------------------------------------------------------------- -function _hdf5plot_read(grp, k::String, T::Type{Font}, dtid) - grp = HDF5.g_open(grp, k) - - family = _hdf5plot_read(grp, "family") - pointsize = _hdf5plot_read(grp, "pointsize") - halign = _hdf5plot_read(grp, "halign") - valign = _hdf5plot_read(grp, "valign") - rotation = _hdf5plot_read(grp, "rotation") - color = _hdf5plot_read(grp, "color") - return Font(family, pointsize, halign, valign, rotation, color) -end -function _hdf5plot_read(grp, k::String, T::Type{Axis}, dtid) - grp = HDF5.g_open(grp, k) - kwlist = KW() - _hdf5plot_read(grp, kwlist) - return Axis([], kwlist) -end - -function _hdf5plot_read(grp, k::String) - dtid = HDF5.a_read(grp[k], _hdf5plot_datatypeid) - T = _hdf5_map_str2telem(dtid) #expect exception - return _hdf5plot_read(grp, k, T, dtid) -end - -#Read in values in group to populate d: -function _hdf5plot_read(grp, d::Dict) - gnames = names(grp) - for k in gnames - try - v = _hdf5plot_read(grp, k) - d[Symbol(k)] = v - catch - warn(k) - end - end - return -end - -# Read main plot structures: -# ---------------------------------------------------------------- - -function _hdf5plot_read(sp::Subplot, subpath::String, f) - f = f::HDF5.HDF5File #Assert - - grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/attr")) - kwlist = KW() - _hdf5plot_read(grp, kwlist) - _hdf5_merge!(sp.attr, kwlist) - - grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list")) - nseries = _hdf5plot_readcount(grp) - - for i in 1:nseries - grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list/series$i")) - kwlist = KW() - _hdf5plot_read(grp, kwlist) - plot!(sp, kwlist[:x], kwlist[:y]) #Add data & create data structures - _hdf5_merge!(sp.series_list[end].d, kwlist) - end - - return -end - -function _hdf5plot_read(plt::Plot, f) - f = f::HDF5.HDF5File #Assert - - grp = HDF5.g_open(f, _hdf5_plotelempath("attr")) - _hdf5plot_read(grp, plt.attr) - - for (i, sp) in enumerate(plt.subplots) - _hdf5plot_read(sp, "subplots/subplot$i", f) - end - - return -end - -function hdf5plot_read(path::AbstractString) - plt = nothing - HDF5.h5open(path, "r") do file - grp = HDF5.g_open(file, _hdf5_plotelempath("subplots")) - n = _hdf5plot_readcount(grp) - plt = plot(layout=n) #Get reference to a new plot - _hdf5plot_read(plt, file) - end - return plt -end - -#Last line From 7a1dd0db29b3f181782842cfec4201282d736d28 Mon Sep 17 00:00:00 2001 From: Godisemo Date: Thu, 20 Apr 2017 17:40:05 +0200 Subject: [PATCH 079/720] Add colorbar_title attr to plotly(js) backends fixes issue #773 --- src/backends/plotly.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index e19759d2..43a1bb70 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -19,7 +19,7 @@ const _plotly_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, + :grid, :legend, :colorbar, :colorbar_title, :marker_z, :fill_z, :levels, :ribbon, :quiver, :orientation, @@ -446,6 +446,8 @@ function plotly_series(plt::Plot, series::Series) end end + d_out[:colorbar] = KW(:title => sp[:colorbar_title]) + clims = sp[:clims] if is_2tuple(clims) d_out[:zmin], d_out[:zmax] = clims From 11e9eb3aa354a5ea07e608cb9d5c35bdbe19efdb Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 23 Apr 2017 20:30:48 +0200 Subject: [PATCH 080/720] allow Int as input type for the ticks attribute to set the desired number of ticks --- src/axes.jl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 7af2d7c5..dae525c3 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -188,6 +188,23 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) k_min = 5, # minimum number of ticks k_max = 8, # maximum number of ticks )[1] + elseif typeof(ticks) <: Int + # only return ticks within the axis limits + filter( + ti -> sf(amin) <= ti <= sf(amax), + optimize_ticks( + sf(amin), + sf(amax); + # TODO: find a better configuration to return the chosen number + # of ticks + k_min = ticks + 1, # minimum number of ticks + k_max = ticks + 2, # maximum number of ticks + k_ideal = ticks + 2, + # `strict_span = false` rewards cases where the span of the + # chosen ticks is not too much bigger than amin - amax: + strict_span = false, + )[1] + ) else map(sf, filter(t -> amin <= t <= amax, ticks)) end @@ -226,7 +243,7 @@ function get_ticks(axis::Axis) elseif ticks == :auto # compute optimal ticks and labels optimal_ticks_and_labels(axis) - elseif typeof(ticks) <: AVec + elseif typeof(ticks) <: Union{AVec, Int} # override ticks, but get the labels optimal_ticks_and_labels(axis, ticks) elseif typeof(ticks) <: NTuple{2} From 6b250d1ab6d29cf1841573ae37ba68c6f0a8cdea Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Tue, 18 Apr 2017 17:46:38 +0200 Subject: [PATCH 081/720] Prevent inadvertent Conda ROOTENV initialization Conda._installed_packages_dict() always runs Conda._install_conda(), even when using an external conda installation (e.g. via Anaconda). --- src/backends/pyplot.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cdc44fb1..1fffcf04 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -89,10 +89,12 @@ function _initialize_backend(::PyPlotBackend) @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 If the code has a Segmentation fault error switch to qt v4.8.5 by pasting the following code into julia: \n \n") - print(add_backend_string(PyPlotBackend())) + if isfile(Conda.conda) # Using Conda-internal conda (instead of an external conda) + 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") + print(add_backend_string(PyPlotBackend())) + end end end end From a602309a02c72359227c1d1d68635cf5b1d37762 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 30 Apr 2017 19:02:42 +0200 Subject: [PATCH 082/720] wip let axis limits expand --- src/axes.jl | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index dae525c3..9dfa18a9 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -181,32 +181,32 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) end # get a list of well-laid-out ticks - scaled_ticks = if ticks == nothing - optimize_ticks( + if ticks == nothing + scaled_ticks = optimize_ticks( sf(amin), sf(amax); k_min = 5, # minimum number of ticks k_max = 8, # maximum number of ticks - )[1] + )[1], sf(amin), sf(amax) elseif typeof(ticks) <: Int - # only return ticks within the axis limits - filter( - ti -> sf(amin) <= ti <= sf(amax), - optimize_ticks( - sf(amin), - sf(amax); - # TODO: find a better configuration to return the chosen number - # of ticks - k_min = ticks + 1, # minimum number of ticks - k_max = ticks + 2, # maximum number of ticks - k_ideal = ticks + 2, - # `strict_span = false` rewards cases where the span of the - # chosen ticks is not too much bigger than amin - amax: - strict_span = false, - )[1] + scaled_ticks, viewmin, viewmax = optimize_ticks( + sf(amin), + sf(amax); + # TODO: find a better configuration to return the chosen number + # of ticks + k_min = ticks, # minimum number of ticks + k_max = ticks, # maximum number of ticks + k_ideal = ticks, + # k_min = ticks + 1, # minimum number of ticks + # k_max = ticks + 2, # maximum number of ticks + # k_ideal = ticks + 2, + # `strict_span = false` rewards cases where the span of the + # chosen ticks is not too much bigger than amin - amax: + strict_span = false, ) + axis[:lims] = map(invscalefunc(scale), (viewmin, viewmax)) else - map(sf, filter(t -> amin <= t <= amax, ticks)) + scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks), amin, amax)) end unscaled_ticks = map(invscalefunc(scale), scaled_ticks) @@ -503,10 +503,10 @@ end # compute the line segments which should be drawn for this axis function axis_drawing_info(sp::Subplot) xaxis, yaxis = sp[:xaxis], sp[:yaxis] - xmin, xmax = axis_limits(xaxis) - ymin, ymax = axis_limits(yaxis) xticks = get_ticks(xaxis) yticks = get_ticks(yaxis) + xmin, xmax = axis_limits(xaxis) + ymin, ymax = axis_limits(yaxis) spine_segs = Segments(2) grid_segs = Segments(2) From 93d16a27c1cb67e7305360429cea15b80eb3f4dc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 30 Apr 2017 19:27:01 +0200 Subject: [PATCH 083/720] undo unnecessary changes --- src/axes.jl | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 9dfa18a9..276d7374 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -187,26 +187,21 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) sf(amax); k_min = 5, # minimum number of ticks k_max = 8, # maximum number of ticks - )[1], sf(amin), sf(amax) + )[1] elseif typeof(ticks) <: Int scaled_ticks, viewmin, viewmax = optimize_ticks( sf(amin), sf(amax); - # TODO: find a better configuration to return the chosen number - # of ticks k_min = ticks, # minimum number of ticks k_max = ticks, # maximum number of ticks k_ideal = ticks, - # k_min = ticks + 1, # minimum number of ticks - # k_max = ticks + 2, # maximum number of ticks - # k_ideal = ticks + 2, # `strict_span = false` rewards cases where the span of the # chosen ticks is not too much bigger than amin - amax: strict_span = false, ) axis[:lims] = map(invscalefunc(scale), (viewmin, viewmax)) else - scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks), amin, amax)) + scaled_ticks = map(sf, (filter(t -> amin <= t <= amax, ticks))) end unscaled_ticks = map(invscalefunc(scale), scaled_ticks) @@ -503,10 +498,10 @@ end # compute the line segments which should be drawn for this axis function axis_drawing_info(sp::Subplot) xaxis, yaxis = sp[:xaxis], sp[:yaxis] - xticks = get_ticks(xaxis) - yticks = get_ticks(yaxis) xmin, xmax = axis_limits(xaxis) ymin, ymax = axis_limits(yaxis) + xticks = get_ticks(xaxis) + yticks = get_ticks(yaxis) spine_segs = Segments(2) grid_segs = Segments(2) From 5e5e1850ac39e7b83ea47f9658375a4b5bb19d20 Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Mon, 1 May 2017 11:04:39 -0400 Subject: [PATCH 084/720] deleted old warning for conda --- src/backends/pyplot.jl | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cdc44fb1..3adfa8a5 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -85,17 +85,7 @@ 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 If the code has a Segmentation fault error switch to qt v4.8.5 by pasting the following code into julia: \n \n") - print(add_backend_string(PyPlotBackend())) - end - end - end + # we don't want every command to update the figure PyPlot.ioff() end From 2e7329931c0faac4c4effbe5f82830bf39c21d7f Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Mon, 1 May 2017 11:14:38 -0400 Subject: [PATCH 085/720] changed warning in imagemagick --- src/animation.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/animation.jl b/src/animation.jl index ee7428df..55a9fe53 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -80,7 +80,8 @@ function buildanimation(animdir::AbstractString, fn::AbstractString; catch err warn("""Tried to create gif using convert (ImageMagick), but got error: $err - ImageMagick can be installed by executing `Pkg.add("ImageMagick")` + ImageMagick can be installed by executing `Pkg.add("ImageMagick")`. + You may also need to install the imagemagick c++ library through your operating system. Will try ffmpeg, but it's lower quality...)""") # low quality From c4f3b93da56a26d8ac8a7734991ab32943c5c62e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 2 May 2017 20:36:33 +0200 Subject: [PATCH 086/720] increase rightpad for colorbars --- 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 cdc44fb1..251e7e61 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1107,7 +1107,7 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend}) # optionally add the width of colorbar labels and colorbar to rightpad if haskey(sp.attr, :cbar_ax) bb = py_bbox(sp.attr[:cbar_handle][:ax][:get_yticklabels]()) - sp.attr[:cbar_width] = _cbar_width + width(bb) + 1mm + (sp[:colorbar_title] == "" ? 0px : 30px) + sp.attr[:cbar_width] = _cbar_width + width(bb) + 2.3mm + (sp[:colorbar_title] == "" ? 0px : 30px) rightpad = rightpad + sp.attr[:cbar_width] end From af072da0b05013c5e954c4171ca59f2ad565f561 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 2 May 2017 21:10:43 +0200 Subject: [PATCH 087/720] avoid auto-reduction of user-defined ticks --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 7af2d7c5..9a39ca2e 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -238,7 +238,7 @@ function get_ticks(axis::Axis) # @show ticks dvals cv dv # TODO: better/smarter cutoff values for sampling ticks - if length(cv) > 30 + if length(cv) > 30 && ticks == :auto rng = Int[round(Int,i) for i in linspace(1, length(cv), 15)] cv[rng], dv[rng] else From 0f837f3438fd4e7bf41075a83bcf604738feba22 Mon Sep 17 00:00:00 2001 From: Sebastian Pech Date: Wed, 3 May 2017 10:39:07 +0200 Subject: [PATCH 088/720] Add pgfplots support for zcolor and colorbar --- src/backends/pgfplots.jl | 55 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 3a47295f..c44c10ae 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -22,8 +22,8 @@ const _pgfplots_attr = merge_with_base_supported([ :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, :grid, :legend, - # :colorbar, - # :marker_z, :levels, + :colorbar, + :marker_z, #:levels, # :ribbon, :quiver, :arrow, # :orientation, # :overwrite_figure, @@ -98,6 +98,8 @@ const _pgf_series_extrastyle = KW( :xsticks => "xcomb", ) +# PGFPlots uses the anchors to define orientations for example to align left +# one needs to use the right edge as anchor const _pgf_annotation_halign = KW( :center => "", :left => "right", @@ -107,11 +109,24 @@ const _pgf_annotation_halign = KW( # -------------------------------------------------------------------------------------- # takes in color,alpha, and returns color and alpha appropriate for pgf style -function pgf_color(c) +function pgf_color(c::Colorant) cstr = @sprintf("{rgb,1:red,%.8f;green,%.8f;blue,%.8f}", red(c), green(c), blue(c)) cstr, alpha(c) end +function pgf_color(grad::ColorGradient) + # Can't handle ColorGradient here, fallback to defaults. + cstr = @sprintf("{rgb,1:red,%.8f;green,%.8f;blue,%.8f}", 0.0, 0.60560316,0.97868012) + cstr, 1 +end + +# Generates a colormap for pgfplots based on a ColorGradient +function pgf_colormap(grad::ColorGradient) + join(map(grad.colors) do c + @sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c),blue(c)) + end,", ") +end + function pgf_fillstyle(d::KW) cstr,a = pgf_color(d[:fillcolor]) "fill = $cstr, fill opacity=$a" @@ -162,7 +177,6 @@ function pgf_series(sp::Subplot, series::Series) st = d[:seriestype] style = [] kw = KW() - push!(style, pgf_linestyle(d)) push!(style, pgf_marker(d)) @@ -182,6 +196,10 @@ function pgf_series(sp::Subplot, series::Series) d[:z].surf, d[:x], d[:y] elseif is3d(st) d[:x], d[:y], d[:z] + elseif d[:marker_z] != nothing + # If a marker_z is used pass it as third coordinate to a 2D plot. + # See "Scatter Plots" in PGFPlots documentation + d[:x], d[:y], d[:marker_z] else d[:x], d[:y] end @@ -274,6 +292,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # Obtain the total height of the plot by extracting the maximal bottom # coordinate from the bounding box. total_height = bottom(bbox(plt.layout)) + for sp in plt.subplots # first build the PGFPlots.Axis object style = ["unbounded coords=jump"] @@ -319,6 +338,34 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) if sp[:projection] == :polar axisf = PGFPlots.PolarAxis end + + # Search series for any gradient. In case one series uses a gradient set + # the colorbar and colomap. + # The reasoning behind doing this on the axis level is that pgfplots + # colorbar seems to only works on axis level and needs the proper colormap for + # correctly displaying it. + # It's also possible to assign the colormap to the series itself but + # then the colormap needs to be added twice, once for the axis and once for the + # series. + # As it is likely that all series within the same axis use the same + # colormap this should not cause any problem. + for series in series_list(sp) + for col in (:markercolor, :fillcolor) + if typeof(series.d[col]) == ColorGradient + push!(style,"colormap={plots}{$(pgf_colormap(series.d[col]))}") + + if sp[:colorbar] == :none + kw[:colorbar] = "false" + else + kw[:colorbar] = "true" + end + # goto is needed to break out of col and series for + @goto colorbar_end + end + end + end + @label colorbar_end + o = axisf(; style = style, kw...) # add the series object to the PGFPlots.Axis From 118823064174714f14698f819fa0e0616b403ce2 Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Sat, 29 Apr 2017 17:48:11 +0200 Subject: [PATCH 089/720] Change histogram implementation, use StatsPlots, add new histogram styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New series recipes for binned data: * barbins * scatterbins * stepbins New series recipes for histogram: * barhist (histogram is now an alias for this) * scatterhist * stephist Supports plotting 1D and 2D StatsBase histograms, seriestype can be set to bar(bins), scatter(bins) or step(bins). Also adds support for some common auto-binning modes: * :sturges, :auto - Sturges' formula * :sqrt - Square-root choice * :rice - Rice Rule * :scott - Scott's normal reference rule * :fd - Freedman–Diaconis rule Maybe these could be contributed to StatsBase at some point. Error bars currently don't work correctly for scatterbins and scatterhist, due to problem with manipulating error bars in a series recipe, but do work for "plot(h::StatsBase.Histogram, seriestype = :scatter)" (works around the problem by calling scatter directly, it seems that error bars can be manipulated correctly in a type recipe). --- REQUIRE | 1 + src/Plots.jl | 4 + src/arg_desc.jl | 4 +- src/args.jl | 8 +- src/pipeline.jl | 2 +- src/recipes.jl | 289 ++++++++++++++++++++++++++++++++++++------------ src/subplots.jl | 2 +- 7 files changed, 232 insertions(+), 78 deletions(-) diff --git a/REQUIRE b/REQUIRE index 67e5f781..14bcddc8 100644 --- a/REQUIRE +++ b/REQUIRE @@ -7,3 +7,4 @@ Reexport FixedSizeArrays Measures Showoff +StatsBase 0.14.0 diff --git a/src/Plots.jl b/src/Plots.jl index 337880da..113242e9 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -9,6 +9,7 @@ using Base.Meta @reexport using PlotUtils @reexport using PlotThemes import Showoff +import StatsBase export grid, @@ -148,6 +149,9 @@ end @shorthands bar @shorthands barh @shorthands histogram +@shorthands barhist +@shorthands stephist +@shorthands scatterhist @shorthands histogram2d @shorthands density @shorthands heatmap diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 4efbf1af..b233d6d7 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector. For histogram-types, defines the number of bins, or the edges, of the histogram.", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. For histogram-types, defines the number of bins, or the edges, of the histogram, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd)", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", @@ -40,7 +40,7 @@ const _arg_desc = KW( :ribbon => "Number or AbstractVector. Creates a fillrange around the data points.", :quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.", :arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.", -:normalize => "Bool. Should normalize histogram types? Trying for area == 1.", +:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a PDF with integral of 1) and :density (only normalize in respect to bin sizes).", :weights => "AbstractVector. Used in histogram types for weighted counts.", :contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.", :match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.", diff --git a/src/args.jl b/src/args.jl index fa5a8e2f..476ce0ea 100644 --- a/src/args.jl +++ b/src/args.jl @@ -35,7 +35,9 @@ const _3dTypes = [ ] const _allTypes = vcat([ :none, :line, :path, :steppre, :steppost, :sticks, :scatter, - :heatmap, :hexbin, :histogram, :histogram2d, :histogram3d, :density, :bar, :hline, :vline, + :heatmap, :hexbin, :barbins, :barhist, :histogram, :scatterbins, + :scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :histogram3d, + :density, :bar, :hline, :vline, :contour, :pie, :shape, :image ], _3dTypes) @@ -78,7 +80,7 @@ const _typeAliases = Dict{Symbol,Symbol}( add_non_underscore_aliases!(_typeAliases) -like_histogram(seriestype::Symbol) = seriestype == :histogram +like_histogram(seriestype::Symbol) = seriestype in (:histogram, :barhist, :barbins) like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :steppost) like_surface(seriestype::Symbol) = seriestype in (:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image) @@ -1261,7 +1263,7 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) end # scatter plots don't have a line, but must have a shape - if d[:seriestype] in (:scatter, :scatter3d) + if d[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) d[:linewidth] = 0 if d[:markershape] == :none d[:markershape] = :circle diff --git a/src/pipeline.jl b/src/pipeline.jl index 6c2e05c3..46cd4bcf 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -357,7 +357,7 @@ function _expand_subplot_extrema(sp::Subplot, d::KW, st::Symbol) expand_extrema!(sp[:xaxis], (0,w)) expand_extrema!(sp[:yaxis], (0,h)) sp[:yaxis].d[:flip] = true - elseif !(st in (:pie, :histogram, :histogram2d)) + elseif !(st in (:pie, :histogram, :bins2d, :histogram2d)) expand_extrema!(sp, d) end end diff --git a/src/recipes.jl b/src/recipes.jl index 5be5b6e0..691a6e45 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -378,109 +378,256 @@ end end @deps bar shape + # --------------------------------------------------------------------------- # Histograms -# edges from number of bins -function calc_edges(v, bins::Integer) - vmin, vmax = extrema(v) - linspace(vmin, vmax, bins+1) +_bin_centers(v::AVec) = (v[1:end-1] + v[2:end]) / 2 + + +@recipe function f(::Type{Val{:barbins}}, x, y, z) + edge, weights = x, y + if (d[:bar_width] == nothing) + bar_width := diff(edge) + end + x := _bin_centers(edge) + y := weights + seriestype := :bar + () +end +@deps barbins bins + + +@recipe function f(::Type{Val{:scatterbins}}, x, y, z) + edge, weights = x, y + xerror := diff(edge)/2 + x := _bin_centers(edge) + y := weights + seriestype := :scatter + () +end +@deps scatterbins scatter + + +function _stepbins_path(edge, weights) + nbins = length(linearindices(weights)) + if length(linearindices(edge)) != nbins + 1 + error("Edge vector must be 1 longer than weight vector") + end + + it_e, it_w = start(edge), start(weights) + px, it_e = next(edge, it_e) + py = zero(eltype(weights)) + + npathpts = 2 * nbins + 2 + x = Vector{eltype(px)}(npathpts) + y = Vector{eltype(py)}(npathpts) + + x[1], y[1] = px, py + i = 2 + while (i < npathpts - 1) + py, it_w = next(weights, it_w) + x[i], y[i] = px, py + i += 1 + px, it_e = next(edge, it_e) + x[i], y[i] = px, py + i += 1 + end + assert(i == npathpts) + x[end], y[end] = px, zero(py) + + (x, y) end -# just pass through arrays -calc_edges(v, bins::AVec) = bins +@recipe function f(::Type{Val{:stepbins}}, x, y, z) + edge, weights = x, y -# find the bucket index of this value -function bucket_index(vi, edges) - for (i,e) in enumerate(edges) - if vi <= e - return max(1,i-1) + axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] + + xpts, ypts = _stepbins_path(edge, weights) + if !Plots.isvertical(d) + xpts, ypts = ypts, xpts + end + + # create a secondary series for the markers + if d[:markershape] != :none + @series begin + seriestype := :scatter + x := Plots._bin_centers(edge) + y := weights + fillrange := nothing + label := "" + primary := false + () end + markershape := :none + xerror := :none + yerror := :none + end + + x := xpts + y := ypts + seriestype := :path + ylims --> [0, 1.1 * maximum(weights)] + () +end +Plots.@deps stepbins path + + +function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) + _cl(x) = max(ceil(Int, x), 1) + _iqr(v) = quantile(v, 0.75) - quantile(v, 0.25) + _span(v) = maximum(v) - minimum(v) + + n_samples = length(linearindices(first(vs))) + # Estimator for number of samples in one row/column of bins along each axis: + n = max(1, n_samples^(1/N)) + + v = vs[dim] + + if mode == :sqrt # Square-root choice + _cl(sqrt(n)) + elseif mode == :sturges || mode ==:auto # Sturges' formula + _cl(log2(n)) + 1 + elseif mode == :rice # Rice Rule + _cl(2 * n^(1/3)) + elseif mode == :scott # Scott's normal reference rule + _cl(_span(v) / (3.5 * std(v) / n^(1/3))) + elseif mode == :fd # Freedman–Diaconis rule + _cl(_span(v) / (2 * _iqr(v) / n^(1/3))) + else + error("Unknown auto-binning mode $mode") end - return length(edges)-1 end -function my_hist(v, bins; normed = false, weights = nothing) - edges = calc_edges(v, bins) - counts = zeros(length(edges)-1) +_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) +_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) +_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning - # add a weighted count - for (i,vi) in enumerate(v) - idx = bucket_index(vi, edges) - counts[idx] += (weights == nothing ? 1.0 : weights[i]) - end +_hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) = + map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...)) - counts = isapprox(extrema(diff(edges))...) ? counts : counts ./ diff(edges) # for uneven bins, normalize to area. +_hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) = + map(dim -> _hist_edge(vs, dim, binning), (1:N...)) - # normalize by bar area? - norm_denom = normed ? sum(diff(edges) .* counts) : 1.0 - if norm_denom == 0 - norm_denom = 1.0 - end +_hist_norm_mode(mode::Symbol) = mode +_hist_norm_mode(mode::Bool) = mode ? :pdf : :none - edges, counts ./ norm_denom +function _make_hist{N}(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) + edges = _hist_edges(vs, binning) + h = float( weights == nothing ? + StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) : + StatsBase.fit(StatsBase.Histogram, vs, weights, edges, closed = :left) + ) + normalize!(h, mode = _hist_norm_mode(normed)) end @recipe function f(::Type{Val{:histogram}}, x, y, z) - edges, counts = my_hist(y, d[:bins], - normed = d[:normalize], - weights = d[:weights]) - bar_width := diff(edges) - x := centers(edges) - y := counts - seriestype := :bar + seriestype := :barhist () end -@deps histogram bar +@deps histogram barhist + +@recipe function f(::Type{Val{:barhist}}, x, y, z) + h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + x := h.edges[1] + y := h.weights + seriestype := :barbins + () +end +@deps barhist barbins + +@recipe function f(::Type{Val{:stephist}}, x, y, z) + h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + x := h.edges[1] + y := h.weights + seriestype := :stepbins + () +end +@deps stephist stepbins + +@recipe function f(::Type{Val{:scatterhist}}, x, y, z) + h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + x := h.edges[1] + y := h.weights + seriestype := :scatterbins + () +end +@deps scatterhist scatterbins + + +@recipe function f{T, E}(h::StatsBase.Histogram{T, 1, E}) + seriestype --> :barbins + + st_map = Dict( + :bar => :barbins, :scatter => :scatterbins, :step => :stepbins, + :steppost => :stepbins # :step can be mapped to :steppost in pre-processing + ) + seriestype := get(st_map, d[:seriestype], d[:seriestype]) + + if d[:seriestype] == :scatterbins + # Workaround, error bars currently not set correctly by scatterbins + xerror --> diff(h.edges[1])/2 + seriestype := :scatter + (Plots._bin_centers(h.edges[1]), h.weights) + else + (h.edges[1], h.weights) + end +end + + +@recipe function f{H <: StatsBase.Histogram}(hv::AbstractVector{H}) + for h in hv + @series begin + h + end + end +end + # --------------------------------------------------------------------------- # Histogram 2D -# if tuple, map out bins, otherwise use the same for both -calc_edges_2d(x, y, bins) = calc_edges(x, bins), calc_edges(y, bins) -calc_edges_2d{X,Y}(x, y, bins::Tuple{X,Y}) = calc_edges(x, bins[1]), calc_edges(y, bins[2]) +@recipe function f(::Type{Val{:bins2d}}, x, y, z) + edge_x, edge_y, weights = x, y, z.surf -# the 2D version -function my_hist_2d(x, y, bins; normed = false, weights = nothing) - xedges, yedges = calc_edges_2d(x, y, bins) - counts = zeros(length(yedges)-1, length(xedges)-1) - - # add a weighted count - for i=1:length(x) - r = bucket_index(y[i], yedges) - c = bucket_index(x[i], xedges) - counts[r,c] += (weights == nothing ? 1.0 : weights[i]) + float_weights = float(weights) + if is(float_weights, weights) + float_weights = deepcopy(float_weights) end - - # normalize to cubic area of the imaginary surface towers - norm_denom = normed ? sum((diff(yedges) * diff(xedges)') .* counts) : 1.0 - if norm_denom == 0 - norm_denom = 1.0 - end - - xedges, yedges, counts ./ norm_denom -end - -centers(v::AVec) = 0.5 * (v[1:end-1] + v[2:end]) - -@recipe function f(::Type{Val{:histogram2d}}, x, y, z) - xedges, yedges, counts = my_hist_2d(x, y, d[:bins], - normed = d[:normalize], - weights = d[:weights]) - for (i,c) in enumerate(counts) + for (i, c) in enumerate(float_weights) if c == 0 - counts[i] = NaN + float_weights[i] = NaN end end - x := centers(xedges) - y := centers(yedges) - z := Surface(counts) - linewidth := 0 + + x := Plots._bin_centers(edge_x) + y := Plots._bin_centers(edge_y) + z := Surface(float_weights) + + match_dimensions := true seriestype := :heatmap () end -@deps histogram2d heatmap +Plots.@deps bins2d heatmap + + +@recipe function f(::Type{Val{:histogram2d}}, x, y, z) + h = _make_hist((x, y), d[:bins], normed = d[:normalize], weights = d[:weights]) + x := h.edges[1] + y := h.edges[2] + z := Surface(h.weights) + seriestype := :bins2d + () +end +@deps histogram2d bins2d + + +@recipe function f{T, E}(h::StatsBase.Histogram{T, 2, E}) + seriestype --> :bins2d + (h.edges[1], h.edges[2], Surface(h.weights)) +end # --------------------------------------------------------------------------- diff --git a/src/subplots.jl b/src/subplots.jl index 3400874c..924cc6c0 100644 --- a/src/subplots.jl +++ b/src/subplots.jl @@ -39,7 +39,7 @@ series_list(sp::Subplot) = sp.series_list # filter(series -> series.d[:subplot] function should_add_to_legend(series::Series) series.d[:primary] && series.d[:label] != "" && !(series.d[:seriestype] in ( - :hexbin,:histogram2d,:hline,:vline, + :hexbin,:bins2d,:histogram2d,:hline,:vline, :contour,:contourf,:contour3d,:surface,:wireframe, :heatmap, :pie, :image )) From 56a9389023745db11308225cae2ecd0a21253f91 Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Sat, 29 Apr 2017 17:53:37 +0200 Subject: [PATCH 090/720] Fix log-scale for 1D bar/bin/histogram series types --- src/args.jl | 2 + src/pipeline.jl | 7 +++ src/recipes.jl | 149 ++++++++++++++++++++++++++++++++++++------------ 3 files changed, 120 insertions(+), 38 deletions(-) diff --git a/src/args.jl b/src/args.jl index 476ce0ea..4f4bba59 100644 --- a/src/args.jl +++ b/src/args.jl @@ -156,6 +156,8 @@ const _markerAliases = Dict{Symbol,Symbol}( ) const _allScales = [:identity, :ln, :log2, :log10, :asinh, :sqrt] +const _logScales = [:ln, :log2, :log10] +const _logScaleBases = Dict(:ln => e, :log2 => 2.0, :log10 => 10.0) const _scaleAliases = Dict{Symbol,Symbol}( :none => :identity, :log => :log10, diff --git a/src/pipeline.jl b/src/pipeline.jl index 46cd4bcf..70644055 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -277,6 +277,13 @@ function _subplot_setup(plt::Plot, d::KW, kw_list::Vector{KW}) attr[Symbol(letter,k)] = v end end + for k in (:scale,), letter in (:x,:y,:z) + # Series recipes may need access to this information + lk = Symbol(letter,k) + if haskey(attr, lk) + kw[lk] = attr[lk] + end + end end sp_attrs[sp] = attr end diff --git a/src/recipes.jl b/src/recipes.jl index 691a6e45..cb89fbc0 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -323,10 +323,11 @@ end # create a bar plot as a filled step function @recipe function f(::Type{Val{:bar}}, x, y, z) - nx, ny = length(x), length(y) + procx, procy, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + nx, ny = length(procx), length(procy) axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis] - cv = [discrete_value!(axis, xi)[1] for xi=x] - x = if nx == ny + cv = [discrete_value!(axis, xi)[1] for xi=procx] + procx = if nx == ny cv elseif nx == ny + 1 0.5diff(cv) + cv[1:end-1] @@ -337,9 +338,9 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5mean(diff(x)) + 0.5mean(diff(procx)) else - Float64[0.5cycle(bw,i) for i=1:length(x)] + Float64[0.5cycle(bw,i) for i=1:length(procx)] end # make fillto a vector... default fills to 0 @@ -347,16 +348,21 @@ end if fillto == nothing fillto = 0 end + if (yscale in _logScales) && !all(_is_positive, fillto) + fillto = map(x -> _is_positive(x) ? typeof(baseline)(x) : baseline, fillto) + end # create the bar shapes by adding x/y segments xseg, yseg = Segments(), Segments() for i=1:ny - center = x[i] - hwi = cycle(hw,i) - yi = y[i] - fi = cycle(fillto,i) - push!(xseg, center-hwi, center-hwi, center+hwi, center+hwi, center-hwi) - push!(yseg, yi, fi, fi, yi, yi) + yi = procy[i] + if !isnan(yi) + center = procx[i] + hwi = cycle(hw,i) + fi = cycle(fillto,i) + push!(xseg, center-hwi, center-hwi, center+hwi, center+hwi, center-hwi) + push!(yseg, yi, fi, fi, yi, yi) + end end # widen limits out a bit @@ -384,9 +390,51 @@ end _bin_centers(v::AVec) = (v[1:end-1] + v[2:end]) / 2 +_is_positive(x) = (x > 0) && !(x ≈ 0) + +_positive_else_nan{T}(::Type{T}, x::Real) = _is_positive(x) ? T(x) : T(NaN) + +function _scale_adjusted_values{T<:AbstractFloat}(::Type{T}, V::AbstractVector, scale::Symbol) + if scale in _logScales + [_positive_else_nan(T, x) for x in V] + else + [T(x) for x in V] + end +end + +function _hist_ylim_lo{T<:Real}(ymin::T, yscale::Symbol) + if (yscale in _logScales) + ymin / T(_logScaleBases[yscale]^log10(2)) + else + zero(T) + end +end + +function _hist_ylim_hi{T<:Real}(ymax::T, yscale::Symbol) + if (yscale in _logScales) + ymax * T(_logScaleBases[yscale]^log10(2)) + else + ymax * T(1.1) + end +end + + +function _preprocess_binlike(d, x, y) + xscale = get(d, :xscale, :identity) + yscale = get(d, :yscale, :identity) + + T = float(promote_type(eltype(x), eltype(y))) + edge = map(T, x) + weights = _scale_adjusted_values(T, y, yscale) + w_min = minimum(weights) + baseline = _hist_ylim_lo(isnan(w_min) ? one(T) : w_min, yscale) + edge, weights, xscale, yscale, baseline +end + + @recipe function f(::Type{Val{:barbins}}, x, y, z) - edge, weights = x, y + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) if (d[:bar_width] == nothing) bar_width := diff(edge) end @@ -395,11 +443,11 @@ _bin_centers(v::AVec) = (v[1:end-1] + v[2:end]) / 2 seriestype := :bar () end -@deps barbins bins +@deps barbins bar @recipe function f(::Type{Val{:scatterbins}}, x, y, z) - edge, weights = x, y + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) xerror := diff(edge)/2 x := _bin_centers(edge) y := weights @@ -409,43 +457,65 @@ end @deps scatterbins scatter -function _stepbins_path(edge, weights) +function _stepbins_path(edge, weights, baseline::Real, xscale::Symbol, yscale::Symbol) + log_scale_x = xscale in _logScales + log_scale_y = yscale in _logScales + nbins = length(linearindices(weights)) if length(linearindices(edge)) != nbins + 1 error("Edge vector must be 1 longer than weight vector") end + x = eltype(edge)[] + y = eltype(weights)[] + it_e, it_w = start(edge), start(weights) - px, it_e = next(edge, it_e) - py = zero(eltype(weights)) + a, it_e = next(edge, it_e) + last_w = eltype(weights)(NaN) + i = 1 + while (!done(edge, it_e) && !done(edge, it_e)) + b, it_e = next(edge, it_e) + w, it_w = next(weights, it_w) - npathpts = 2 * nbins + 2 - x = Vector{eltype(px)}(npathpts) - y = Vector{eltype(py)}(npathpts) + if (log_scale_x && a ≈ 0) + a = b/_logScaleBases[xscale]^3 + end - x[1], y[1] = px, py - i = 2 - while (i < npathpts - 1) - py, it_w = next(weights, it_w) - x[i], y[i] = px, py - i += 1 - px, it_e = next(edge, it_e) - x[i], y[i] = px, py - i += 1 + if isnan(w) + if !isnan(last_w) + push!(x, a) + push!(y, baseline) + end + else + if isnan(last_w) + push!(x, a) + push!(y, baseline) + end + push!(x, a) + push!(y, w) + push!(x, b) + push!(y, w) + end + + a = b + last_w = w + end + if (last_w != baseline) + push!(x, a) + push!(y, baseline) end - assert(i == npathpts) - x[end], y[end] = px, zero(py) (x, y) end -@recipe function f(::Type{Val{:stepbins}}, x, y, z) - edge, weights = x, y +@recipe function f(::Type{Val{:stepbins}}, x, y, z) axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] - xpts, ypts = _stepbins_path(edge, weights) - if !Plots.isvertical(d) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + + xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale) + if !isvertical(d) xpts, ypts = ypts, xpts end @@ -453,7 +523,7 @@ end if d[:markershape] != :none @series begin seriestype := :scatter - x := Plots._bin_centers(edge) + x := _bin_centers(edge) y := weights fillrange := nothing label := "" @@ -468,7 +538,8 @@ end x := xpts y := ypts seriestype := :path - ylims --> [0, 1.1 * maximum(weights)] + + ylims --> [baseline, _hist_ylim_hi(maximum(weights), yscale)] () end Plots.@deps stepbins path @@ -568,9 +639,11 @@ end if d[:seriestype] == :scatterbins # Workaround, error bars currently not set correctly by scatterbins + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) + info("xscale = $xscale, yscale = $yscale") xerror --> diff(h.edges[1])/2 seriestype := :scatter - (Plots._bin_centers(h.edges[1]), h.weights) + (Plots._bin_centers(edge), weights) else (h.edges[1], h.weights) end From c22a9e51a16b7e353137fc7a4b2e01648b9a788d Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 4 May 2017 13:15:05 +0200 Subject: [PATCH 091/720] Update News.md --- NEWS.md | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index c1c98498..8cd7a38e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,7 +10,40 @@ --- -## 0.9 (current master/dev) +## 0.11 (current master/dev) + +#### 0.11.0 + +- julia 0.6 compatibility +- matplotlib 0.2.0 compatibility +- add inspectdr backend +- improved histogram functionality: +- added a `:stephist` and `:scatterhist` series type as well as ``:barhist` (the default) +- support for log scale axes with histograms +- support for plotting `StatsBase.Histogram` +- allowing bins to be specified as `:sturges`, `:rice`, `:scott` or :fd +- allow `normalization` to be specified as :density (for unequal bins) or :pdf (sum to 1) +- add a `plotattr` function to access documentation for Plots attribute +- add `fill_z` attribute for pyplot +- add colorbar_title to plotlyjs +- enable standalone window for plotlyjs +- improved support for pgfplots, ticks rotation, clims, series_annotations +- restore colorbars for GR +- better axis labels for heatmap in GR +- better marker sizes in GR +- fix color representation in GR +- update GR legend +- fix image bug on GR +- fix glvisualize dependencies +- set dotted grid lines for pyplot +- several improvements to inspectdr +- improved tick positions for TimeType x axes +- support for improved color gradient capability in PlotUtils +- add a showlibrary recipe to display color libraries +- add a showgradient recipe to display color gradients +- add `vectorfield` as an alias for `quiver` +- use `PlotUtils.adaptedgrid` for functions + #### 0.9.5 From c75e1df190f2aeafa1bb0572577adcc91674a877 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 4 May 2017 16:28:49 +0200 Subject: [PATCH 092/720] gr: fixed linewidth bug (lw=0) --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 24ddfd42..c41c38ba 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -338,7 +338,7 @@ end function gr_set_line(lw, style, c) #, a) GR.setlinetype(gr_linetype[style]) w, h = gr_plot_size - GR.setlinewidth(max(1, lw / ((w + h) * 0.001))) + GR.setlinewidth(max(0, lw / ((w + h) * 0.001))) gr_set_linecolor(c) #, a) end From a523903c154a4c3d43c7ab0543b2b23ad519e911 Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Sat, 6 May 2017 10:13:04 +0200 Subject: [PATCH 093/720] Remove remnant debugging output --- src/recipes.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index cb89fbc0..37210363 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -640,7 +640,6 @@ end if d[:seriestype] == :scatterbins # Workaround, error bars currently not set correctly by scatterbins edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) - info("xscale = $xscale, yscale = $yscale") xerror --> diff(h.edges[1])/2 seriestype := :scatter (Plots._bin_centers(edge), weights) From 67b4157e254fdfe910132bea9b3fcb1a3f0f2a1d Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Sat, 6 May 2017 15:00:31 +0200 Subject: [PATCH 094/720] Improve data preprocessing for bar and histogram plots Fixes broken bar-plots with non-numeric a-axes --- src/recipes.jl | 68 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 37210363..ef37f184 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -323,7 +323,7 @@ end # create a bar plot as a filled step function @recipe function f(::Type{Val{:bar}}, x, y, z) - procx, procy, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + procx, procy, xscale, yscale, baseline, wautolims = _preprocess_barlike(d, x, y) nx, ny = length(procx), length(procy) axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis] cv = [discrete_value!(axis, xi)[1] for xi=procx] @@ -380,6 +380,7 @@ end x := xseg.pts y := yseg.pts seriestype := :shape + ylims --> wautolims () end @deps bar shape @@ -402,39 +403,64 @@ function _scale_adjusted_values{T<:AbstractFloat}(::Type{T}, V::AbstractVector, end end -function _hist_ylim_lo{T<:Real}(ymin::T, yscale::Symbol) - if (yscale in _logScales) - ymin / T(_logScaleBases[yscale]^log10(2)) + +function _binbarlike_baseline{T<:Real}(min_value::T, scale::Symbol) + if (scale in _logScales) + !isnan(min_value) ? min_value / T(_logScaleBases[scale]^log10(2)) : T(1E-3) else zero(T) end end -function _hist_ylim_hi{T<:Real}(ymax::T, yscale::Symbol) - if (yscale in _logScales) - ymax * T(_logScaleBases[yscale]^log10(2)) +function _binbarlike_autolims{T<:Real}(min_value::T, max_value::T, scale::Symbol) + lo = if (scale in _logScales) + _binbarlike_baseline(min_value, scale) else - ymax * T(1.1) - end + min(min_value * T(1.1), zero(T)) + end::T + + hi = if !isnan(max_value) + if (scale in _logScales) + max_value * T(_logScaleBases[scale]^log10(2)) + else + max(max_value * T(1.1), zero(T)) + end + else + one(T) + end::T + + (lo, hi) end +function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) + w_adj = _scale_adjusted_values(T, w, wscale) + w_min = minimum(w_adj) + w_max = maximum(w_adj) + baseline = _binbarlike_baseline(w_min, wscale) + autolims = _binbarlike_autolims(w_min, w_max,wscale) + w_adj, baseline, autolims +end + +function _preprocess_barlike(d, x, y) + xscale = get(d, :xscale, :identity) + yscale = get(d, :yscale, :identity) + weights, baseline, wautolims = _preprocess_binbarlike_weights(float(eltype(y)), y, yscale) + x, weights, xscale, yscale, baseline, wautolims +end + function _preprocess_binlike(d, x, y) xscale = get(d, :xscale, :identity) yscale = get(d, :yscale, :identity) - T = float(promote_type(eltype(x), eltype(y))) - edge = map(T, x) - weights = _scale_adjusted_values(T, y, yscale) - w_min = minimum(weights) - baseline = _hist_ylim_lo(isnan(w_min) ? one(T) : w_min, yscale) - edge, weights, xscale, yscale, baseline + edge = T.(x) + weights, baseline, wautolims = _preprocess_binbarlike_weights(T, y, yscale) + edge, weights, xscale, yscale, baseline, wautolims end - @recipe function f(::Type{Val{:barbins}}, x, y, z) - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) if (d[:bar_width] == nothing) bar_width := diff(edge) end @@ -447,7 +473,7 @@ end @recipe function f(::Type{Val{:scatterbins}}, x, y, z) - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) xerror := diff(edge)/2 x := _bin_centers(edge) y := weights @@ -512,7 +538,7 @@ end @recipe function f(::Type{Val{:stepbins}}, x, y, z) axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale) if !isvertical(d) @@ -539,7 +565,7 @@ end y := ypts seriestype := :path - ylims --> [baseline, _hist_ylim_hi(maximum(weights), yscale)] + ylims --> wautolims () end Plots.@deps stepbins path @@ -639,7 +665,7 @@ end if d[:seriestype] == :scatterbins # Workaround, error bars currently not set correctly by scatterbins - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) + edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, h.edges[1], h.weights) xerror --> diff(h.edges[1])/2 seriestype := :scatter (Plots._bin_centers(edge), weights) From 784382110945b37e9d2acbbb1fe82a7b6ca2ac05 Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Mon, 8 May 2017 11:36:01 +0200 Subject: [PATCH 095/720] Change default for bins to :auto (meaning 30 bins) --- src/arg_desc.jl | 2 +- src/args.jl | 2 +- src/recipes.jl | 9 ++++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index b233d6d7..cea77071 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. For histogram-types, defines the number of bins, or the edges, of the histogram, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd)", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the number of bins, or the edges, of the histogram, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd)", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", diff --git a/src/args.jl b/src/args.jl index 4f4bba59..b93e2d98 100644 --- a/src/args.jl +++ b/src/args.jl @@ -185,7 +185,7 @@ const _series_defaults = KW( :markerstrokewidth => 1, :markerstrokecolor => :match, :markerstrokealpha => nothing, - :bins => 30, # number of bins for hists + :bins => :auto, # number of bins for hists :smooth => false, # regression line? :group => nothing, # groupby vector :x => nothing, diff --git a/src/recipes.jl b/src/recipes.jl index ef37f184..115ffa79 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -582,9 +582,11 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode v = vs[dim] - if mode == :sqrt # Square-root choice + if mode == :auto + 30 + elseif mode == :sqrt # Square-root choice _cl(sqrt(n)) - elseif mode == :sturges || mode ==:auto # Sturges' formula + elseif mode == :sturges # Sturges' formula _cl(log2(n)) + 1 elseif mode == :rice # Rice Rule _cl(2 * n^(1/3)) @@ -594,7 +596,7 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode _cl(_span(v) / (2 * _iqr(v) / n^(1/3))) else error("Unknown auto-binning mode $mode") - end + end::Int end _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) @@ -611,6 +613,7 @@ _hist_norm_mode(mode::Symbol) = mode _hist_norm_mode(mode::Bool) = mode ? :pdf : :none function _make_hist{N}(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) + info("binning = $binning") edges = _hist_edges(vs, binning) h = float( weights == nothing ? StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) : From 698d583d1d261e01d0d17e364db16c1e9d0c1ab7 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 8 May 2017 15:16:21 -0500 Subject: [PATCH 096/720] Fix world-age problem with IJulia --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index f3efd812..84225e9b 100644 --- a/src/output.jl +++ b/src/output.jl @@ -271,7 +271,7 @@ function setup_ijulia() show(io, MIME("text/html"), plt) end end - set_ijulia_output("text/html") + @eval set_ijulia_output("text/html") end end From 10f214fbb4cb700e0ad800c96eee6bab38c51c02 Mon Sep 17 00:00:00 2001 From: David Sanders Date: Mon, 8 May 2017 15:20:21 -0500 Subject: [PATCH 097/720] Change typealias to const --- NEWS.md | 2 +- src/Plots.jl | 2 +- src/components.jl | 4 ++-- src/deprecated/series_args.jl | 2 +- src/series.jl | 2 +- src/types.jl | 8 ++++---- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8cd7a38e..dcf896a1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -364,7 +364,7 @@ - z-axis keywords - 3D indexing overhaul: `push!`, `append!` support - matplotlib colormap constants (`:inferno` is the new default colormap for Plots) -- `typealias KW Dict{Symbol,Any}` used in place of splatting in many places +- `const KW = Dict{Symbol,Any}` used in place of splatting in many places - png generation for plotly backend using wkhtmltoimage - `normalize` and `weights` keywords - background/foreground subcategories for fine-tuning of looks diff --git a/src/Plots.jl b/src/Plots.jl index 113242e9..7e630ad7 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -108,7 +108,7 @@ export import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h -typealias BBox Measures.Absolute2DBox +const BBox = Measures.Absolute2DBox export BBox, BoundingBox, mm, cm, inch, pt, px, pct, w, h # --------------------------------------------------------- diff --git a/src/components.jl b/src/components.jl index 551fbee8..b20eb3d0 100644 --- a/src/components.jl +++ b/src/components.jl @@ -1,7 +1,7 @@ -typealias P2 FixedSizeArrays.Vec{2,Float64} -typealias P3 FixedSizeArrays.Vec{3,Float64} +const P2 = FixedSizeArrays.Vec{2,Float64} +const P3 = FixedSizeArrays.Vec{3,Float64} nanpush!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); push!(a, b)) nanappend!(a::AbstractVector{P2}, b) = (push!(a, P2(NaN,NaN)); append!(a, b)) diff --git a/src/deprecated/series_args.jl b/src/deprecated/series_args.jl index 7d491290..2d7536f4 100644 --- a/src/deprecated/series_args.jl +++ b/src/deprecated/series_args.jl @@ -5,7 +5,7 @@ # This should cut down on boilerplate code and allow more focused dispatch on type # note: returns meta information... mainly for use with automatic labeling from DataFrames for now -typealias FuncOrFuncs @compat(Union{Function, AVec{Function}}) +const FuncOrFuncs = @compat(Union{Function, AVec{Function}}) all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) diff --git a/src/series.jl b/src/series.jl index f7233c1a..cf9756c5 100644 --- a/src/series.jl +++ b/src/series.jl @@ -6,7 +6,7 @@ # This should cut down on boilerplate code and allow more focused dispatch on type # note: returns meta information... mainly for use with automatic labeling from DataFrames for now -typealias FuncOrFuncs{F} Union{F, Vector{F}, Matrix{F}} +const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) diff --git a/src/types.jl b/src/types.jl index 0f1e4909..284b6534 100644 --- a/src/types.jl +++ b/src/types.jl @@ -2,9 +2,9 @@ # TODO: I declare lots of types here because of the lacking ability to do forward declarations in current Julia # I should move these to the relevant files when something like "extern" is implemented -typealias AVec AbstractVector -typealias AMat AbstractMatrix -typealias KW Dict{Symbol,Any} +const AVec = AbstractVector +const AMat = AbstractMatrix +const KW = Dict{Symbol,Any} immutable PlotsDisplay <: Display end @@ -62,7 +62,7 @@ Extrema() = Extrema(Inf, -Inf) # ----------------------------------------------------------- -typealias SubplotMap Dict{Any, Subplot} +const SubplotMap = Dict{Any, Subplot} # ----------------------------------------------------------- From 5e6a9da3ed5d6cd856ad499659b6a60eb2af8944 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 8 May 2017 14:36:25 -0700 Subject: [PATCH 098/720] gr: use correct colorbar scaling --- src/backends/gr.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c41c38ba..0566da5a 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -813,12 +813,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end + GR.setspace(zmin, zmax, 0, 90) if typeof(series[:levels]) <: Array h = series[:levels] else h = linspace(zmin, zmax, series[:levels]) end - GR.setspace(zmin, zmax, 0, 90) if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else @@ -856,6 +856,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end + GR.setspace(zmin, zmax, 0, 90) grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad() colors = [grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)] for zi=z] rgba = map(c -> UInt32( round(Int, alpha(c) * 255) << 24 + From d893034f47ec38e2a3173aa0fcc999f433c362b3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 9 May 2017 09:31:09 +0200 Subject: [PATCH 099/720] Amend news.md --- NEWS.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8cd7a38e..f2d65ed4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,8 +3,8 @@ #### notes on release changes, ongoing development, and future planned work -- All new development should target 0.9! -- Minor version 0.8 is the last one to support Julia 0.4!! +- All new development should target 0.12! +- Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - `backports` branch is for Julia 0.4 From b88d26ce77739a2a243bcbaac6e1c1d8ea2d2b87 Mon Sep 17 00:00:00 2001 From: fuzzybear3965 Date: Tue, 9 May 2017 12:29:35 -0400 Subject: [PATCH 100/720] increase bottom margin to 20px; fixes #810 --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 43a1bb70..1626d5e2 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -269,7 +269,7 @@ function plotly_layout(plt::Plot) w, h = plt[:size] d_out[:width], d_out[:height] = w, h d_out[:paper_bgcolor] = rgba_string(plt[:background_color_outside]) - d_out[:margin] = KW(:l=>0, :b=>0, :r=>0, :t=>20) + d_out[:margin] = KW(:l=>0, :b=>20, :r=>0, :t=>20) d_out[:annotations] = KW[] From ee15b2c166924cb1620094bcb3c5437ebc90442e Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Thu, 11 May 2017 00:31:30 -0700 Subject: [PATCH 101/720] Fix plotpane notice PlotlyJS actually plots to the plot pane, so the text was misleading. --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index f3efd812..ec424d54 100644 --- a/src/output.jl +++ b/src/output.jl @@ -318,7 +318,7 @@ function setup_atom() # special handling for plotly... use PlotsDisplay function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend}) display(Plots.PlotsDisplay(), plt) - s = "PlotPane turned off. The plotly and plotlyjs backends cannot render in the PlotPane due to javascript issues." + s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." Media.render(pane, Atom.div(Atom.HTML(s))) end end From d5e50983d87d6a8d6c5a3a7517eac559c7e9f8b2 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 11 May 2017 13:40:10 +0200 Subject: [PATCH 102/720] Move rgba_string to PlotUtils requested by Tony Kelman --- src/backends/plotly.jl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1626d5e2..814e4775 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -413,9 +413,6 @@ plotly_surface_data(series::Series, a::Surface) = plotly_surface_data(series, a. as_gradient(grad::ColorGradient, α) = grad as_gradient(grad, α) = cgrad(alpha = α) -# allows passing a ColorGradient where a single color is expected - the other backends allow this -PlotUtils.rgba_string(cg::ColorGradient) = rgba_string(cg[1]) - # get a dictionary representing the series params (d is the Plots-dict, d_out is the Plotly-dict) function plotly_series(plt::Plot, series::Series) st = series[:seriestype] From 8656fe002a51f5cfbe590f440930d898646c75e7 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 11 May 2017 13:40:39 +0200 Subject: [PATCH 103/720] Add minimum version numbers to PlotUtils and PlotThemes --- REQUIRE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/REQUIRE b/REQUIRE index 14bcddc8..26866772 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,8 +1,8 @@ julia 0.5 RecipesBase -PlotUtils -PlotThemes +PlotUtils 0.4 +PlotThemes 0.1.2 Reexport FixedSizeArrays Measures From 160b2bf03a3806805f925fa7e4410674bcd464c4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 11 May 2017 14:00:29 +0200 Subject: [PATCH 104/720] Up minor version number --- REQUIRE | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/REQUIRE b/REQUIRE index 26866772..5875b39d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,8 +1,8 @@ julia 0.5 RecipesBase -PlotUtils 0.4 -PlotThemes 0.1.2 +PlotUtils 0.4.1 +PlotThemes 0.1.3 Reexport FixedSizeArrays Measures From b8c8c491761070f21e4200082390751607e1d5b2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 11 May 2017 22:45:04 +0200 Subject: [PATCH 105/720] update version number for testing --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 71f94924..44264d71 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -24,7 +24,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.9.6" +const _current_plots_version = v"0.11.1" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From d24f327342dca187634930b6d0f3f6467498c3c0 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 12 May 2017 11:42:26 +0200 Subject: [PATCH 106/720] Switch off precompilation for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 113242e9..785bbe24 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 4b8dc06ddb7ec487db0b31765defac63f9577b9d Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 12 May 2017 11:45:46 +0200 Subject: [PATCH 107/720] Switch precompilation back on --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 785bbe24..113242e9 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From eced31e3d7e8dbcb06658c793089514f0033d6ad Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 12 May 2017 11:46:51 +0200 Subject: [PATCH 108/720] Update version number in tests --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 44264d71..890c374b 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -24,7 +24,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.11.1" +const _current_plots_version = v"0.11.2" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 0e6a02b8105a3f1190befb70d2a3da8047fee0bd Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 13 May 2017 23:46:29 +0200 Subject: [PATCH 109/720] make precompilation work on o.5 --- src/series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index cf9756c5..f7233c1a 100644 --- a/src/series.jl +++ b/src/series.jl @@ -6,7 +6,7 @@ # This should cut down on boilerplate code and allow more focused dispatch on type # note: returns meta information... mainly for use with automatic labeling from DataFrames for now -const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} +typealias FuncOrFuncs{F} Union{F, Vector{F}, Matrix{F}} all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) From 746f96cdcd9243f2b5c5d83e1da0015fe8cceaee Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Mon, 15 May 2017 23:26:30 +0200 Subject: [PATCH 110/720] Remove ylims default setting for bar and histogram plots Setting `ylims -> ...` doesn't play well with multiple series and cannot be properly overridden by user. --- src/recipes.jl | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 115ffa79..1bc4cad5 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -323,7 +323,7 @@ end # create a bar plot as a filled step function @recipe function f(::Type{Val{:bar}}, x, y, z) - procx, procy, xscale, yscale, baseline, wautolims = _preprocess_barlike(d, x, y) + procx, procy, xscale, yscale, baseline = _preprocess_barlike(d, x, y) nx, ny = length(procx), length(procy) axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis] cv = [discrete_value!(axis, xi)[1] for xi=procx] @@ -380,7 +380,6 @@ end x := xseg.pts y := yseg.pts seriestype := :shape - ylims --> wautolims () end @deps bar shape @@ -412,41 +411,20 @@ function _binbarlike_baseline{T<:Real}(min_value::T, scale::Symbol) end end -function _binbarlike_autolims{T<:Real}(min_value::T, max_value::T, scale::Symbol) - lo = if (scale in _logScales) - _binbarlike_baseline(min_value, scale) - else - min(min_value * T(1.1), zero(T)) - end::T - - hi = if !isnan(max_value) - if (scale in _logScales) - max_value * T(_logScaleBases[scale]^log10(2)) - else - max(max_value * T(1.1), zero(T)) - end - else - one(T) - end::T - - (lo, hi) -end - function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) w_adj = _scale_adjusted_values(T, w, wscale) w_min = minimum(w_adj) w_max = maximum(w_adj) baseline = _binbarlike_baseline(w_min, wscale) - autolims = _binbarlike_autolims(w_min, w_max,wscale) - w_adj, baseline, autolims + w_adj, baseline end function _preprocess_barlike(d, x, y) xscale = get(d, :xscale, :identity) yscale = get(d, :yscale, :identity) - weights, baseline, wautolims = _preprocess_binbarlike_weights(float(eltype(y)), y, yscale) - x, weights, xscale, yscale, baseline, wautolims + weights, baseline = _preprocess_binbarlike_weights(float(eltype(y)), y, yscale) + x, weights, xscale, yscale, baseline end function _preprocess_binlike(d, x, y) @@ -454,13 +432,13 @@ function _preprocess_binlike(d, x, y) yscale = get(d, :yscale, :identity) T = float(promote_type(eltype(x), eltype(y))) edge = T.(x) - weights, baseline, wautolims = _preprocess_binbarlike_weights(T, y, yscale) - edge, weights, xscale, yscale, baseline, wautolims + weights, baseline = _preprocess_binbarlike_weights(T, y, yscale) + edge, weights, xscale, yscale, baseline end @recipe function f(::Type{Val{:barbins}}, x, y, z) - edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) if (d[:bar_width] == nothing) bar_width := diff(edge) end @@ -473,7 +451,7 @@ end @recipe function f(::Type{Val{:scatterbins}}, x, y, z) - edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) xerror := diff(edge)/2 x := _bin_centers(edge) y := weights @@ -538,7 +516,7 @@ end @recipe function f(::Type{Val{:stepbins}}, x, y, z) axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] - edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale) if !isvertical(d) @@ -564,8 +542,6 @@ end x := xpts y := ypts seriestype := :path - - ylims --> wautolims () end Plots.@deps stepbins path @@ -668,7 +644,7 @@ end if d[:seriestype] == :scatterbins # Workaround, error bars currently not set correctly by scatterbins - edge, weights, xscale, yscale, baseline, wautolims = _preprocess_binlike(d, h.edges[1], h.weights) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) xerror --> diff(h.edges[1])/2 seriestype := :scatter (Plots._bin_centers(edge), weights) From 2fbc3c954ae2ecf85d1bdc6cbb2c0c585df68a59 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 16 May 2017 07:32:14 +0200 Subject: [PATCH 111/720] fix filling stepstyle on pyplot --- src/backends/pyplot.jl | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cf9790aa..df426bbb 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -221,6 +221,12 @@ function py_stepstyle(seriestype::Symbol) return "default" end +function py_fillstepstyle(seriestype::Symbol) + seriestype == :steppost && return "post" + seriestype == :steppre && return "pre" + return nothing +end + # # untested... return a FontProperties object from a Plots.Font # function py_font(font::Font) # pyfont.pymember("FontProperties")( @@ -868,7 +874,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) end - handle = ax[f](args...; + handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); zorder = series[:series_plotindex], facecolor = py_fillcolor(series), linewidths = 0 From 5c5472262668a431b7c8674013ac2dc8bdcc5b26 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 16 May 2017 11:28:38 +0200 Subject: [PATCH 112/720] changed xor in gr.jl --- src/backends/gr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 697e2471..dafa7e35 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -668,8 +668,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) for (cv, dv) in zip(xticks...) - # use xor ($) to get the right y coords - xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin) + # use xor (⊻) to get the right y coords + xi, yi = GR.wctondc(cv, (flip ⊻ mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) gr_text(xi, yi + (mirror ? 1 : -1) * 2e-3, string(dv)) end @@ -685,8 +685,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) color = sp[:yaxis][:foreground_color_axis], rotation = sp[:yaxis][:rotation]) for (cv, dv) in zip(yticks...) - # use xor ($) to get the right y coords - xi, yi = GR.wctondc((flip $ mirror) ? xmax : xmin, cv) + # use xor (⊻) to get the right y coords + xi, yi = GR.wctondc((flip ⊻ mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi gr_text(xi + (mirror ? 1 : -1) * 2e-3, yi, string(dv)) end From db341f18148afe4b91cec61daf87d9c8c8badc54 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 16 May 2017 11:28:38 +0200 Subject: [PATCH 113/720] Revert "changed xor in gr.jl" This reverts commit 5c5472262668a431b7c8674013ac2dc8bdcc5b26. --- src/backends/gr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index dafa7e35..697e2471 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -668,8 +668,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) for (cv, dv) in zip(xticks...) - # use xor (⊻) to get the right y coords - xi, yi = GR.wctondc(cv, (flip ⊻ mirror) ? ymax : ymin) + # use xor ($) to get the right y coords + xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) gr_text(xi, yi + (mirror ? 1 : -1) * 2e-3, string(dv)) end @@ -685,8 +685,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) color = sp[:yaxis][:foreground_color_axis], rotation = sp[:yaxis][:rotation]) for (cv, dv) in zip(yticks...) - # use xor (⊻) to get the right y coords - xi, yi = GR.wctondc((flip ⊻ mirror) ? xmax : xmin, cv) + # use xor ($) to get the right y coords + xi, yi = GR.wctondc((flip $ mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi gr_text(xi + (mirror ? 1 : -1) * 2e-3, yi, string(dv)) end From d4ef1761e4188f1ffb68aa88fb07b360391b3eed Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 16 May 2017 21:32:57 +0200 Subject: [PATCH 114/720] change skipped images because of new example --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 953ad8fe..2bc0af8b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -23,7 +23,7 @@ facts("PyPlot") do @fact pyplot() --> Plots.PyPlotBackend() @fact backend() --> Plots.PyPlotBackend() - image_comparison_facts(:pyplot, skip=[6,25,30], eps=img_eps) + image_comparison_facts(:pyplot, skip=[6,26,31], eps=img_eps) end facts("GR") do @@ -31,7 +31,7 @@ facts("GR") do @fact backend() --> Plots.GRBackend() if is_linux() && isinteractive() - image_comparison_facts(:gr, skip=[2,25,30], eps=img_eps) + image_comparison_facts(:gr, skip=[2,26,31], eps=img_eps) end end From 1f7ecb969ca8013fdad9e4833939008280a163af Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 16 May 2017 21:43:22 +0200 Subject: [PATCH 115/720] move new PlotExample to the end for VRT --- src/examples.jl | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 9f54509d..2fd6a0e9 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -172,24 +172,6 @@ PlotExample("", end)] ), -PlotExample("Animation with subplots", - "The `layout` macro can be used to create an animation with subplots.", - [:(begin - l = @layout([[a; b] c]) - p = plot(plot([sin,cos],1,leg=false), - scatter([atan,cos],1,leg=false), - plot(log,1,xlims=(1,10π),ylims=(0,5),leg=false),layout=l) - - anim = Animation() - for x = linspace(1,10π,100) - plot(push!(p,x,Float64[sin(x),cos(x),atan(x),cos(x),log(x)])) - frame(anim) - end - end)] -), - - - PlotExample("Open/High/Low/Close", "Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y` argument. This uses recipes to first convert the tuples to OHLC objects, and subsequently create a :path series with the appropriate line segments.", [:(begin @@ -318,7 +300,23 @@ PlotExample("Boxplot and Violin series recipes", violin(singers, :VoicePart, :Height, line = 0, fill = (0.2, :blue)) boxplot!(singers, :VoicePart, :Height, line = (2,:black), fill = (0.3, :orange)) end)] -) +), + +PlotExample("Animation with subplots", + "The `layout` macro can be used to create an animation with subplots.", + [:(begin + l = @layout([[a; b] c]) + p = plot(plot([sin,cos],1,leg=false), + scatter([atan,cos],1,leg=false), + plot(log,1,xlims=(1,10π),ylims=(0,5),leg=false),layout=l) + + anim = Animation() + for x = linspace(1,10π,100) + plot(push!(p,x,Float64[sin(x),cos(x),atan(x),cos(x),log(x)])) + frame(anim) + end + end)] +), ] From 89cd67792b302482143539c352aa5c9e6f401ca2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 16 May 2017 21:46:11 +0200 Subject: [PATCH 116/720] update numbers of skipped examples in VRT --- test/runtests.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 2bc0af8b..94f95a1b 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -23,7 +23,7 @@ facts("PyPlot") do @fact pyplot() --> Plots.PyPlotBackend() @fact backend() --> Plots.PyPlotBackend() - image_comparison_facts(:pyplot, skip=[6,26,31], eps=img_eps) + image_comparison_facts(:pyplot, skip=[6,25,30,31], eps=img_eps) end facts("GR") do @@ -31,7 +31,7 @@ facts("GR") do @fact backend() --> Plots.GRBackend() if is_linux() && isinteractive() - image_comparison_facts(:gr, skip=[2,26,31], eps=img_eps) + image_comparison_facts(:gr, skip=[2,25,30,31], eps=img_eps) end end From b920ee8550e770a0207b380bd9355adc08503a5a Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Sun, 14 May 2017 22:23:09 -0400 Subject: [PATCH 117/720] Re-integrate HDF5 plots. Made code compatible with Julia v0.6. Parametric types no longer <: DataType (now <: Type). Add workaround to initialize Dict with "Type" keys. --- src/backends.jl | 1 + src/backends/hdf5.jl | 504 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 505 insertions(+) create mode 100644 src/backends/hdf5.jl diff --git a/src/backends.jl b/src/backends.jl index 779b91cc..5458a6c0 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -277,6 +277,7 @@ end @init_backend GLVisualize @init_backend PGFPlots @init_backend InspectDR +@init_backend HDF5 # --------------------------------------------------------- diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl new file mode 100644 index 00000000..b2ce25cd --- /dev/null +++ b/src/backends/hdf5.jl @@ -0,0 +1,504 @@ +#HDF5 Plots: Save/replay plots to/from HDF5 +#------------------------------------------------------------------------------- + +#==Usage +=============================================================================== +Write to .hdf5 file using: + p = plot(...) + Plots.hdf5plot_write(p, "plotsave.hdf5") + +Read from .hdf5 file using: + pyplot() #Must first select backend + pread = Plots.hdf5plot_read("plotsave.hdf5") + display(pread) +==# + + +#==TODO +=============================================================================== + 1. Support more features + - SeriesAnnotations & GridLayout known to be missing. + 3. Improve error handling. + - Will likely crash if file format is off. + 2. Save data in a folder parallel to "plot". + - Will make it easier for users to locate data. + - Use HDF5 reference to link data? + 3. Develop an actual versioned file format. + - Should have some form of backward compatibility. + - Should be reliable for archival purposes. +==# + + +import FixedPointNumbers: N0f8 #In core Julia +immutable HDF5PlotNative; end #Dispatch type + + +#==Useful constants +===============================================================================# +const _hdf5_plotroot = "plot" +const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (easier to locate)? +const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type +const _hdf5plot_countid = "COUNT" #Attribute for storing count + +#Possible element types of high-level data types: +const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}( + "NATIVE" => HDF5PlotNative, + "VOID" => Void, + "BOOL" => Bool, + "SYMBOL" => Symbol, + "TUPLE" => Tuple, + "RGBA" => ARGB{N0f8}, + "EXTREMA" => Extrema, + "LENGTH" => Length, + + #Sub-structure types: + "FONT" => Font, + "AXIS" => Axis, +) + +#Dict has problems using "Types" as keys. Initialize in "_initialize_backend": +#const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM) +const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}() + + +#== +===============================================================================# + +const _hdf5_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, + :fillrange, :fillcolor, :fillalpha, + :bins, :bar_width, :bar_edges, :bar_position, + :title, :title_location, :titlefont, + :window_title, + :guide, :lims, :ticks, :scale, :flip, :rotation, + :tickfont, :guidefont, :legendfont, + :grid, :legend, :colorbar, + :marker_z, :line_z, :fill_z, + :levels, + :ribbon, :quiver, :arrow, + :orientation, + :overwrite_figure, + :polar, + :normalize, :weights, + :contours, :aspect_ratio, + :match_dimensions, + :clims, + :inset_subplots, + :dpi, + :colorbar_title, + ]) +const _hdf5_seriestype = [ + :path, :steppre, :steppost, :shape, + :scatter, :hexbin, #:histogram2d, :histogram, + # :bar, + :heatmap, :pie, :image, + :contour, :contour3d, :path3d, :scatter3d, :surface, :wireframe + ] +const _hdf5_style = [:auto, :solid, :dash, :dot, :dashdot] +const _hdf5_marker = vcat(_allMarkers, :pixel) +const _hdf5_scale = [:identity, :ln, :log2, :log10] +is_marker_supported(::HDF5Backend, shape::Shape) = true + +function add_backend_string(::HDF5Backend) + """ + if !Plots.is_installed("HDF5") + Pkg.add("HDF5") + end + """ +end + + +#==Helper functions +===============================================================================# + +_hdf5_plotelempath(subpath::String) = "$_hdf5_plotroot/$subpath" +_hdf5_datapath(subpath::String) = "$_hdf5_dataroot/$subpath" +_hdf5_map_str2telem(k::String) = HDF5PLOT_MAP_STR2TELEM[k] +_hdf5_map_str2telem(v::Vector) = HDF5PLOT_MAP_STR2TELEM[v[1]] + +function _hdf5_merge!(dest::Dict, src::Dict) + for (k, v) in src + if isa(v, Axis) + _hdf5_merge!(dest[k].d, v.d) + else + dest[k] = v + end + end + return +end + + +#== +===============================================================================# + +function _initialize_backend(::HDF5Backend) + @eval begin + import HDF5 + export HDF5 + if length(HDF5PLOT_MAP_TELEM2STR) < 1 + merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM)) + end + end +end + +# --------------------------------------------------------------------------- + +# Create the window/figure for this backend. +function _create_backend_figure(plt::Plot{HDF5Backend}) + #Do nothing +end + +# --------------------------------------------------------------------------- + +# # this is called early in the pipeline, use it to make the plot current or something +# function _prepare_plot_object(plt::Plot{HDF5Backend}) +# end + +# --------------------------------------------------------------------------- + +# Set up the subplot within the backend object. +function _initialize_subplot(plt::Plot{HDF5Backend}, sp::Subplot{HDF5Backend}) + #Do nothing +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{HDF5Backend}, series::Series) + #Do nothing +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{HDF5Backend}, series::Series) + #Do nothing +end + +# --------------------------------------------------------------------------- + +# called just before updating layout bounding boxes... in case you need to prep +# for the calcs +function _before_layout_calcs(plt::Plot{HDF5Backend}) + #Do nothing +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{HDF5Backend}) + #Do nothing +end + +# ---------------------------------------------------------------- + +# Override this to update plot items (title, xlabel, etc), and add annotations (d[:annotations]) +function _update_plot_object(plt::Plot{HDF5Backend}) + #Do nothing +end + +# ---------------------------------------------------------------- + +_show(io::IO, mime::MIME"text/plain", plt::Plot{HDF5Backend}) = nothing #Don't show + +# ---------------------------------------------------------------- + +# Display/show the plot (open a GUI window, or browser page, for example). +function _display(plt::Plot{HDF5Backend}) + msg = "HDF5 interface does not support `display()` function." + msg *= "\nUse `Plots.hdf5plot_write(::String)` method to write to .HDF5 \"plot\" file instead." + warn(msg) + return +end + + +#==HDF5 write functions +===============================================================================# + +function _hdf5plot_writetype(grp, k::String, tstr::Array{String}) + d = HDF5.d_open(grp, k) + HDF5.a_write(d, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype(grp, k::String, T::Type) + tstr = HDF5PLOT_MAP_TELEM2STR[T] + d = HDF5.d_open(grp, k) + HDF5.a_write(d, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype(grp, T::Type) #Write directly to group + tstr = HDF5PLOT_MAP_TELEM2STR[T] + HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writecount(grp, n::Int) #Write directly to group + HDF5.a_write(grp, _hdf5plot_countid, n) +end +function _hdf5plot_gwritefields(grp, k::String, v) + grp = HDF5.g_create(grp, k) + for _k in fieldnames(v) + _v = getfield(v, _k) + kstr = string(_k) + _hdf5plot_gwrite(grp, kstr, _v) + end + _hdf5plot_writetype(grp, typeof(v)) + return +end + +# Write data +# ---------------------------------------------------------------- + +function _hdf5plot_gwrite(grp, k::String, v) #Default + grp[k] = v + _hdf5plot_writetype(grp, k, HDF5PlotNative) +end +function _hdf5plot_gwrite(grp, k::String, v::Array{Any}) +# @show grp, k +# warn("Cannot write Array: $k=$v") +end +function _hdf5plot_gwrite(grp, k::String, v::Void) + grp[k] = 0 + _hdf5plot_writetype(grp, k, Void) +end +function _hdf5plot_gwrite(grp, k::String, v::Bool) + grp[k] = Int(v) + _hdf5plot_writetype(grp, k, Bool) +end +function _hdf5plot_gwrite(grp, k::String, v::Symbol) + grp[k] = string(v) + _hdf5plot_writetype(grp, k, Symbol) +end +function _hdf5plot_gwrite(grp, k::String, v::Tuple) + varr = [v...] + if isleaftype(eltype(varr)) + grp[k] = [v...] + _hdf5plot_writetype(grp, k, Tuple) + else + warn("Cannot write tuple: $k=$v") + end +end +function _hdf5plot_gwrite(grp, k::String, d::Dict) +# warn("Cannot write dict: $k=$d") +end +function _hdf5plot_gwrite(grp, k::String, v::Range) + _hdf5plot_gwrite(grp, k, collect(v)) #For now +end +function _hdf5plot_gwrite(grp, k::String, v::ARGB{N0f8}) + grp[k] = [v.r.i, v.g.i, v.b.i, v.alpha.i] + _hdf5plot_writetype(grp, k, ARGB{N0f8}) +end +function _hdf5plot_gwrite(grp, k::String, v::Colorant) + _hdf5plot_gwrite(grp, k, ARGB{N0f8}(v)) +end +function _hdf5plot_gwrite{T<:Colorant}(grp, k::String, v::Vector{T}) + #TODO +end +function _hdf5plot_gwrite(grp, k::String, v::Extrema) + grp[k] = [v.emin, v.emax] + _hdf5plot_writetype(grp, k, Extrema) +end +function _hdf5plot_gwrite{T}(grp, k::String, v::Length{T}) + grp[k] = v.value + _hdf5plot_writetype(grp, k, [HDF5PLOT_MAP_TELEM2STR[Length], string(T)]) +end + +# Write more complex structures: +# ---------------------------------------------------------------- + +function _hdf5plot_gwrite(grp, k::String, v::Union{Plot,Subplot}) +# @show :PLOTREF, k + #Don't write plot references +end +function _hdf5plot_gwrite(grp, k::String, v::Font) + _hdf5plot_gwritefields(grp, k, v) + return +end +function _hdf5plot_gwrite(grp, k::String, v::Axis) + grp = HDF5.g_create(grp, k) + for (_k, _v) in v.d + kstr = string(_k) + _hdf5plot_gwrite(grp, kstr, _v) + end + _hdf5plot_writetype(grp, Axis) + return +end + +function _hdf5plot_write(grp, d::Dict) + for (k, v) in d + kstr = string(k) + _hdf5plot_gwrite(grp, kstr, v) + end + return +end + +# Write main plot structures: +# ---------------------------------------------------------------- + +function _hdf5plot_write(sp::Subplot{HDF5Backend}, subpath::String, f) + f = f::HDF5.HDF5File #Assert + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/attr")) + _hdf5plot_write(grp, sp.attr) + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list")) + _hdf5plot_writecount(grp, length(sp.series_list)) + for (i, series) in enumerate(sp.series_list) + grp = HDF5.g_create(f, _hdf5_plotelempath("$subpath/series_list/series$i")) + _hdf5plot_write(grp, series.d) + end + + return +end + +function _hdf5plot_write(plt::Plot{HDF5Backend}, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_create(f, _hdf5_plotelempath("attr")) + _hdf5plot_write(grp, plt.attr) + + grp = HDF5.g_create(f, _hdf5_plotelempath("subplots")) + _hdf5plot_writecount(grp, length(plt.subplots)) + + for (i, sp) in enumerate(plt.subplots) + _hdf5plot_write(sp, "subplots/subplot$i", f) + end + + return +end +function hdf5plot_write(plt::Plot{HDF5Backend}, path::AbstractString) + HDF5.h5open(path, "w") do file + _hdf5plot_write(plt, file) + end +end +hdf5plot_write(path::AbstractString) = hdf5plot_write(current(), path) + + +#==HDF5 playback (read) functions +===============================================================================# + +function _hdf5plot_readcount(grp) #Read directly from group + return HDF5.a_read(grp, _hdf5plot_countid) +end + +_hdf5plot_convert(T::Type{HDF5PlotNative}, v) = v +_hdf5plot_convert(T::Type{Void}, v) = nothing +_hdf5plot_convert(T::Type{Bool}, v) = (v!=0) +_hdf5plot_convert(T::Type{Symbol}, v) = Symbol(v) +_hdf5plot_convert(T::Type{Tuple}, v) = (v...) +function _hdf5plot_convert(T::Type{ARGB{N0f8}}, v) + r, g, b, a = reinterpret(N0f8, v) + return Colors.ARGB{N0f8}(r, g, b, a) +end +_hdf5plot_convert(T::Type{Extrema}, v) = Extrema(v[1], v[2]) + +# Read data structures: +# ---------------------------------------------------------------- + +function _hdf5plot_read(grp, k::String, T::Type, dtid) + v = HDF5.d_read(grp, k) + return _hdf5plot_convert(T, v) +end +function _hdf5plot_read(grp, k::String, T::Type{Length}, dtid::Vector) + v = HDF5.d_read(grp, k) + TU = Symbol(dtid[2]) + T = typeof(v) + return Length{TU,T}(v) +end + +# Read more complex data structures: +# ---------------------------------------------------------------- +function _hdf5plot_read(grp, k::String, T::Type{Font}, dtid) + grp = HDF5.g_open(grp, k) + + family = _hdf5plot_read(grp, "family") + pointsize = _hdf5plot_read(grp, "pointsize") + halign = _hdf5plot_read(grp, "halign") + valign = _hdf5plot_read(grp, "valign") + rotation = _hdf5plot_read(grp, "rotation") + color = _hdf5plot_read(grp, "color") + return Font(family, pointsize, halign, valign, rotation, color) +end +function _hdf5plot_read(grp, k::String, T::Type{Axis}, dtid) + grp = HDF5.g_open(grp, k) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + return Axis([], kwlist) +end + +function _hdf5plot_read(grp, k::String) + dtid = HDF5.a_read(grp[k], _hdf5plot_datatypeid) + T = _hdf5_map_str2telem(dtid) #expect exception + return _hdf5plot_read(grp, k, T, dtid) +end + +#Read in values in group to populate d: +function _hdf5plot_read(grp, d::Dict) + gnames = names(grp) + for k in gnames + try + v = _hdf5plot_read(grp, k) + d[Symbol(k)] = v + catch + warn(k) + end + end + return +end + +# Read main plot structures: +# ---------------------------------------------------------------- + +function _hdf5plot_read(sp::Subplot, subpath::String, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/attr")) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + _hdf5_merge!(sp.attr, kwlist) + + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list")) + nseries = _hdf5plot_readcount(grp) + + for i in 1:nseries + grp = HDF5.g_open(f, _hdf5_plotelempath("$subpath/series_list/series$i")) + kwlist = KW() + _hdf5plot_read(grp, kwlist) + plot!(sp, kwlist[:x], kwlist[:y]) #Add data & create data structures + _hdf5_merge!(sp.series_list[end].d, kwlist) + end + + return +end + +function _hdf5plot_read(plt::Plot, f) + f = f::HDF5.HDF5File #Assert + + grp = HDF5.g_open(f, _hdf5_plotelempath("attr")) + _hdf5plot_read(grp, plt.attr) + + for (i, sp) in enumerate(plt.subplots) + _hdf5plot_read(sp, "subplots/subplot$i", f) + end + + return +end + +function hdf5plot_read(path::AbstractString) + plt = nothing + HDF5.h5open(path, "r") do file + grp = HDF5.g_open(file, _hdf5_plotelempath("subplots")) + n = _hdf5plot_readcount(grp) + plt = plot(layout=n) #Get reference to a new plot + _hdf5plot_read(plt, file) + end + return plt +end + +#Last line From 8b8de6bcd3f4e93ddf02dd93fe4d31c194d8b186 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Tue, 16 May 2017 19:20:55 -0400 Subject: [PATCH 118/720] Move where backends.jl is included. Must ensure all types required by HDF5 plots are defined. --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 7e630ad7..96326ea8 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -118,7 +118,6 @@ include("utils.jl") include("components.jl") include("axes.jl") include("args.jl") -include("backends.jl") include("themes.jl") include("plot.jl") include("pipeline.jl") @@ -131,6 +130,7 @@ include("output.jl") include("examples.jl") include("arg_desc.jl") include("plotattr.jl") +include("backends.jl") # --------------------------------------------------------- From 64dd69f550d8bbe2a50f258b57dd100912637693 Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Tue, 16 May 2017 19:21:35 -0400 Subject: [PATCH 119/720] Improve robustness More generic Array support. Add support for ColorGradient. Don't crash if plot specifies GridLayout. (Does not properly restore info on layout). --- src/backends/hdf5.jl | 217 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 184 insertions(+), 33 deletions(-) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index b2ce25cd..a3a200ad 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -30,7 +30,14 @@ Read from .hdf5 file using: import FixedPointNumbers: N0f8 #In core Julia -immutable HDF5PlotNative; end #Dispatch type + +#Dispatch types: +immutable HDF5PlotNative; end #Indentifies a data element that can natively be handled by HDF5 +immutable HDF5CTuple; end #Identifies a "complex" tuple structure + +type HDF5Plot_PlotRef + ref::Union{Plot, Void} +end #==Useful constants @@ -40,26 +47,18 @@ const _hdf5_dataroot = "data" #TODO: Eventually move data to different root (eas const _hdf5plot_datatypeid = "TYPE" #Attribute identifying type const _hdf5plot_countid = "COUNT" #Attribute for storing count -#Possible element types of high-level data types: -const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}( - "NATIVE" => HDF5PlotNative, - "VOID" => Void, - "BOOL" => Bool, - "SYMBOL" => Symbol, - "TUPLE" => Tuple, - "RGBA" => ARGB{N0f8}, - "EXTREMA" => Extrema, - "LENGTH" => Length, - - #Sub-structure types: - "FONT" => Font, - "AXIS" => Axis, -) - #Dict has problems using "Types" as keys. Initialize in "_initialize_backend": -#const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM) +const HDF5PLOT_MAP_STR2TELEM = Dict{String, Type}() const HDF5PLOT_MAP_TELEM2STR = Dict{Type, String}() +#Don't really like this global variable... Very hacky +const HDF5PLOT_PLOTREF = HDF5Plot_PlotRef(nothing) + +#Simple sub-structures that can just be written out using _hdf5plot_gwritefields: +const HDF5PLOT_SIMPLESUBSTRUCT = Union{Font, BoundingBox, + GridLayout, RootLayout, ColorGradient, SeriesAnnotations, PlotText +} + #== ===============================================================================# @@ -143,6 +142,32 @@ function _initialize_backend(::HDF5Backend) import HDF5 export HDF5 if length(HDF5PLOT_MAP_TELEM2STR) < 1 + #Possible element types of high-level data types: + const telem2str = Dict{String, Type}( + "NATIVE" => HDF5PlotNative, + "VOID" => Void, + "BOOL" => Bool, + "SYMBOL" => Symbol, + "TUPLE" => Tuple, + "CTUPLE" => HDF5CTuple, #Tuple of complex structures + "RGBA" => ARGB{N0f8}, + "EXTREMA" => Extrema, + "LENGTH" => Length, + "ARRAY" => Array, #Dict won't allow Array to be key in HDF5PLOT_MAP_TELEM2STR + + #Sub-structure types: + "FONT" => Font, + "BOUNDINGBOX" => BoundingBox, + "GRIDLAYOUT" => GridLayout, + "ROOTLAYOUT" => RootLayout, + "SERIESANNOTATIONS" => SeriesAnnotations, +# "PLOTTEXT" => PlotText, + "COLORGRADIENT" => ColorGradient, + "AXIS" => Axis, + "SUBPLOT" => Subplot, + "NULLABLE" => Nullable, + ) + merge!(HDF5PLOT_MAP_STR2TELEM, telem2str) merge!(HDF5PLOT_MAP_TELEM2STR, Dict{Type, String}(v=>k for (k,v) in HDF5PLOT_MAP_STR2TELEM)) end end @@ -236,10 +261,29 @@ function _hdf5plot_writetype(grp, k::String, T::Type) d = HDF5.d_open(grp, k) HDF5.a_write(d, _hdf5plot_datatypeid, tstr) end +function _hdf5plot_overwritetype(grp, k::String, T::Type) + tstr = HDF5PLOT_MAP_TELEM2STR[T] + d = HDF5.d_open(grp, k) + HDF5.a_delete(d, _hdf5plot_datatypeid) + HDF5.a_write(d, _hdf5plot_datatypeid, tstr) +end function _hdf5plot_writetype(grp, T::Type) #Write directly to group tstr = HDF5PLOT_MAP_TELEM2STR[T] HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) end +function _hdf5plot_overwritetype(grp, T::Type) #Write directly to group + tstr = HDF5PLOT_MAP_TELEM2STR[T] + HDF5.a_delete(grp, _hdf5plot_datatypeid) + HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype{T<:Any}(grp, ::Type{Array{T}}) + tstr = HDF5PLOT_MAP_TELEM2STR[Array] #ANY + HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) +end +function _hdf5plot_writetype{T<:BoundingBox}(grp, ::Type{T}) + tstr = HDF5PLOT_MAP_TELEM2STR[BoundingBox] + HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) +end function _hdf5plot_writecount(grp, n::Int) #Write directly to group HDF5.a_write(grp, _hdf5plot_countid, n) end @@ -261,10 +305,16 @@ function _hdf5plot_gwrite(grp, k::String, v) #Default grp[k] = v _hdf5plot_writetype(grp, k, HDF5PlotNative) end +function _hdf5plot_gwrite{T<:Number}(grp, k::String, v::Array{T}) #Default for arrays + grp[k] = v + _hdf5plot_writetype(grp, k, HDF5PlotNative) +end +#= function _hdf5plot_gwrite(grp, k::String, v::Array{Any}) # @show grp, k -# warn("Cannot write Array: $k=$v") + warn("Cannot write Array: $k=$v") end +=# function _hdf5plot_gwrite(grp, k::String, v::Void) grp[k] = 0 _hdf5plot_writetype(grp, k, Void) @@ -279,12 +329,17 @@ function _hdf5plot_gwrite(grp, k::String, v::Symbol) end function _hdf5plot_gwrite(grp, k::String, v::Tuple) varr = [v...] - if isleaftype(eltype(varr)) - grp[k] = [v...] - _hdf5plot_writetype(grp, k, Tuple) - else - warn("Cannot write tuple: $k=$v") + elt = eltype(varr) +# if isleaftype(elt) + + _hdf5plot_gwrite(grp, k, varr) + if elt <: Number + #We just wrote a simple dataset + _hdf5plot_overwritetype(grp, k, Tuple) + else #Used a more complex scheme (using subgroups): + _hdf5plot_overwritetype(grp[k], HDF5CTuple) end + #NOTE: _hdf5plot_overwritetype overwrites "Array" type with "Tuple". end function _hdf5plot_gwrite(grp, k::String, d::Dict) # warn("Cannot write dict: $k=$d") @@ -299,9 +354,28 @@ end function _hdf5plot_gwrite(grp, k::String, v::Colorant) _hdf5plot_gwrite(grp, k, ARGB{N0f8}(v)) end -function _hdf5plot_gwrite{T<:Colorant}(grp, k::String, v::Vector{T}) - #TODO +#Custom vector (when not using simple numeric type): +function _hdf5plot_gwritearray{T}(grp, k::String, v::Array{T}) + if "annotations" == k; + return #Hack. Does not yet support annotations. + end + + vgrp = HDF5.g_create(grp, k) + _hdf5plot_writetype(vgrp, Array) #ANY + sz = size(v) + + for iter in eachindex(v) + coord = ind2sub(sz, iter) + elem = v[iter] + idxstr = join(coord, "_") + _hdf5plot_gwrite(vgrp, "v$idxstr", v[iter]) + end + + _hdf5plot_gwrite(vgrp, "dim", [sz...]) + return end +_hdf5plot_gwrite(grp, k::String, v::Array) = + _hdf5plot_gwritearray(grp, k, v) function _hdf5plot_gwrite(grp, k::String, v::Extrema) grp[k] = [v.emin, v.emax] _hdf5plot_writetype(grp, k, Extrema) @@ -314,11 +388,10 @@ end # Write more complex structures: # ---------------------------------------------------------------- -function _hdf5plot_gwrite(grp, k::String, v::Union{Plot,Subplot}) -# @show :PLOTREF, k +function _hdf5plot_gwrite(grp, k::String, v::Plot) #Don't write plot references end -function _hdf5plot_gwrite(grp, k::String, v::Font) +function _hdf5plot_gwrite(grp, k::String, v::HDF5PLOT_SIMPLESUBSTRUCT) _hdf5plot_gwritefields(grp, k, v) return end @@ -331,7 +404,26 @@ function _hdf5plot_gwrite(grp, k::String, v::Axis) _hdf5plot_writetype(grp, Axis) return end +#TODO: "Properly" support Nullable using _hdf5plot_writetype? +function _hdf5plot_gwrite(grp, k::String, v::Nullable) + if isnull(v) + _hdf5plot_gwrite(grp, k, nothing) + else + _hdf5plot_gwrite(grp, k, v.value) + end + return +end +function _hdf5plot_gwrite(grp, k::String, v::SeriesAnnotations) + #Currently no support for SeriesAnnotations + return +end +function _hdf5plot_gwrite(grp, k::String, v::Subplot) + grp = HDF5.g_create(grp, k) + _hdf5plot_gwrite(grp, "index", v[:subplot_index]) + _hdf5plot_writetype(grp, Subplot) + return +end function _hdf5plot_write(grp, d::Dict) for (k, v) in d kstr = string(k) @@ -391,7 +483,7 @@ _hdf5plot_convert(T::Type{HDF5PlotNative}, v) = v _hdf5plot_convert(T::Type{Void}, v) = nothing _hdf5plot_convert(T::Type{Bool}, v) = (v!=0) _hdf5plot_convert(T::Type{Symbol}, v) = Symbol(v) -_hdf5plot_convert(T::Type{Tuple}, v) = (v...) +_hdf5plot_convert(T::Type{Tuple}, v) = tuple(v...) #With Vector{T<:Number} function _hdf5plot_convert(T::Type{ARGB{N0f8}}, v) r, g, b, a = reinterpret(N0f8, v) return Colors.ARGB{N0f8}(r, g, b, a) @@ -425,13 +517,68 @@ function _hdf5plot_read(grp, k::String, T::Type{Font}, dtid) color = _hdf5plot_read(grp, "color") return Font(family, pointsize, halign, valign, rotation, color) end +function _hdf5plot_read(grp, k::String, T::Type{Array}, dtid) #ANY + grp = HDF5.g_open(grp, k) + sz = _hdf5plot_read(grp, "dim") + if [0] == sz; return []; end + sz = tuple(sz...) + result = Array{Any}(sz) + + for iter in eachindex(result) + coord = ind2sub(sz, iter) + idxstr = join(coord, "_") + result[iter] = _hdf5plot_read(grp, "v$idxstr") + end + + #Hack: Implicitly make Julia detect element type. + # (Should probably write it explicitly to file) + result = [result[iter] for iter in eachindex(result)] #Potentially make more specific + return reshape(result, sz) +end +function _hdf5plot_read(grp, k::String, T::Type{HDF5CTuple}, dtid) + v = _hdf5plot_read(grp, k, Array, dtid) + return tuple(v...) +end +function _hdf5plot_read(grp, k::String, T::Type{ColorGradient}, dtid) + grp = HDF5.g_open(grp, k) + + colors = _hdf5plot_read(grp, "colors") + values = _hdf5plot_read(grp, "values") + return ColorGradient(colors, values) +end +function _hdf5plot_read(grp, k::String, T::Type{BoundingBox}, dtid) + grp = HDF5.g_open(grp, k) + + x0 = _hdf5plot_read(grp, "x0") + a = _hdf5plot_read(grp, "a") + return BoundingBox(x0, a) +end +_hdf5plot_read(grp, k::String, T::Type{RootLayout}, dtid) = RootLayout() +function _hdf5plot_read(grp, k::String, T::Type{GridLayout}, dtid) + grp = HDF5.g_open(grp, k) + +# parent = _hdf5plot_read(grp, "parent") +parent = RootLayout() + minpad = _hdf5plot_read(grp, "minpad") + bbox = _hdf5plot_read(grp, "bbox") + grid = _hdf5plot_read(grp, "grid") + widths = _hdf5plot_read(grp, "widths") + heights = _hdf5plot_read(grp, "heights") + attr = KW() #TODO support attr: _hdf5plot_read(grp, "attr") + + return GridLayout(parent, minpad, bbox, grid, widths, heights, attr) +end function _hdf5plot_read(grp, k::String, T::Type{Axis}, dtid) grp = HDF5.g_open(grp, k) kwlist = KW() _hdf5plot_read(grp, kwlist) return Axis([], kwlist) end - +function _hdf5plot_read(grp, k::String, T::Type{Subplot}, dtid) + grp = HDF5.g_open(grp, k) + idx = _hdf5plot_read(grp, "index") + return HDF5PLOT_PLOTREF.ref.subplots[idx] +end function _hdf5plot_read(grp, k::String) dtid = HDF5.a_read(grp[k], _hdf5plot_datatypeid) T = _hdf5_map_str2telem(dtid) #expect exception @@ -445,8 +592,10 @@ function _hdf5plot_read(grp, d::Dict) try v = _hdf5plot_read(grp, k) d[Symbol(k)] = v - catch - warn(k) + catch e + @show e + @show grp + warn("Could not read field $k") end end return @@ -479,7 +628,9 @@ end function _hdf5plot_read(plt::Plot, f) f = f::HDF5.HDF5File #Assert + #Assumpltion: subplots are already allocated (plt.subplots) + HDF5PLOT_PLOTREF.ref = plt #Used when reading "layout" grp = HDF5.g_open(f, _hdf5_plotelempath("attr")) _hdf5plot_read(grp, plt.attr) From 99e4408da4911d64aca305e284a1a108639e9b25 Mon Sep 17 00:00:00 2001 From: Elliot Saba Date: Tue, 16 May 2017 17:25:27 -0700 Subject: [PATCH 120/720] Update CI URLs to point to new caching infrastructure --- appveyor.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 21481951..c0464e36 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,9 @@ environment: matrix: - - JULIAVERSION: "julialang/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe" - - JULIAVERSION: "julialang/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe" - - JULIAVERSION: "julianightlies/bin/winnt/x86/julia-latest-win32.exe" - - JULIAVERSION: "julianightlies/bin/winnt/x64/julia-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" notifications: - provider: Email @@ -12,13 +12,14 @@ notifications: on_build_status_changed: false install: + - ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12" # If there's a newer build queued for the same PR, cancel this one - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` throw "There are newer queued builds for this pull request, failing early." } # Download most recent Julia Windows binary - - ps: (new-object net.webclient).DownloadFile($("http://s3.amazonaws.com/"+$env:JULIAVERSION), "C:\projects\julia-binary.exe") + - ps: (new-object net.webclient).DownloadFile($env:JULIA_URL, "C:\projects\julia-binary.exe") # Run installer silently, output to C:\projects\julia - C:\projects\julia-binary.exe /S /D=C:\projects\julia From af56d6f2650fe24fda7beb64a8eab43eba6f0fa3 Mon Sep 17 00:00:00 2001 From: Florian Oswald Date: Wed, 17 May 2017 15:31:26 +0200 Subject: [PATCH 121/720] added resetfontsizes() --- src/components.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components.jl b/src/components.jl index b20eb3d0..bff21a7c 100644 --- a/src/components.jl +++ b/src/components.jl @@ -303,6 +303,18 @@ function scalefontsizes(factor::Number) end end +function resetfontsize(k::Symbol) + f = default(k) + default(k,f) +end + +"Reset all fonts to default size" +function resetfontsizes() + for k in (:titlefont, :guidefont, :tickfont, :legendfont) + resetfontsize(k, factor) + end +end + "Wrap a string with font info" immutable PlotText str::AbstractString From e3ce1ab1d153859aa4b4c34a4d56ed9498f6a0af Mon Sep 17 00:00:00 2001 From: Florian Oswald Date: Wed, 17 May 2017 15:40:47 +0200 Subject: [PATCH 122/720] just calling default(k) does not give back the default value for k --- src/components.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index bff21a7c..116aa86c 100644 --- a/src/components.jl +++ b/src/components.jl @@ -311,7 +311,7 @@ end "Reset all fonts to default size" function resetfontsizes() for k in (:titlefont, :guidefont, :tickfont, :legendfont) - resetfontsize(k, factor) + resetfontsize(k) end end From fdf699bf3537ff3208b0097f8aad43e2956490b4 Mon Sep 17 00:00:00 2001 From: Florian Oswald Date: Wed, 17 May 2017 16:34:03 +0200 Subject: [PATCH 123/720] added const copies of _all_defaults and _axis_defaults to be able to reset fonts to initial values with new resetfontsizes method --- src/args.jl | 22 ++++++++++++++++++++++ src/components.jl | 9 +++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index b93e2d98..be5c564c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -335,6 +335,10 @@ const _all_defaults = KW[ _axis_defaults_byletter ] +# to be able to reset things to initial values +const _all_initial_defaults = deepcopy(_all_defaults) +const _axis_initial_defaults = deepcopy(_axis_defaults) + const _all_args = sort(collect(union(map(keys, _all_defaults)...))) RecipesBase.is_key_supported(k::Symbol) = is_attr_supported(k) @@ -519,6 +523,24 @@ function default(d::KW, k::Symbol) get(d, k, default(k)) end +# reset the defaults globally to values at startup + +""" +`initial(key)` returns the intial value for that key +""" + +function initial(k::Symbol) + k = get(_keyAliases, k, k) + for defaults in _all_initial_defaults + if haskey(defaults, k) + return defaults[k] + end + end + if haskey(_axis_initial_defaults, k) + return _axis_initial_defaults[k] + end + k in _suppress_warnings || error("Unknown key: ", k) +end # ----------------------------------------------------------------------------- diff --git a/src/components.jl b/src/components.jl index 116aa86c..e7eb74d6 100644 --- a/src/components.jl +++ b/src/components.jl @@ -304,11 +304,16 @@ function scalefontsizes(factor::Number) end function resetfontsize(k::Symbol) + i = initial(k) f = default(k) - default(k,f) + # some fonts don't have an initial value! + if i != false + f.pointsize = i.pointsize + default(k, i) + end end -"Reset all fonts to default size" +"Reset all fonts to initial size" function resetfontsizes() for k in (:titlefont, :guidefont, :tickfont, :legendfont) resetfontsize(k) From 9c2c548874f0d782cfe5522ea3aaa9b12ebe31e9 Mon Sep 17 00:00:00 2001 From: Florian Oswald Date: Wed, 17 May 2017 17:10:21 +0200 Subject: [PATCH 124/720] create dict _initial_fontsizes and copy from that. creates new method scalefontsizes() [no keyword] --- src/args.jl | 8 +++++--- src/components.jl | 24 +++++++++--------------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/args.jl b/src/args.jl index be5c564c..f93aeae6 100644 --- a/src/args.jl +++ b/src/args.jl @@ -335,9 +335,11 @@ const _all_defaults = KW[ _axis_defaults_byletter ] -# to be able to reset things to initial values -const _all_initial_defaults = deepcopy(_all_defaults) -const _axis_initial_defaults = deepcopy(_axis_defaults) +# to be able to reset font sizes to initial values +const _initial_fontsizes = Dict(:titlefont => deepcopy(_subplot_defaults[:titlefont]), + :legendfont => deepcopy(_subplot_defaults[:legendfont]), + :tickfont => deepcopy(_axis_defaults[:tickfont]), + :guidefont => deepcopy(_axis_defaults[:guidefont])) const _all_args = sort(collect(union(map(keys, _all_defaults)...))) diff --git a/src/components.jl b/src/components.jl index e7eb74d6..1f53f2d1 100644 --- a/src/components.jl +++ b/src/components.jl @@ -303,21 +303,15 @@ function scalefontsizes(factor::Number) end end -function resetfontsize(k::Symbol) - i = initial(k) - f = default(k) - # some fonts don't have an initial value! - if i != false - f.pointsize = i.pointsize - default(k, i) - end -end - -"Reset all fonts to initial size" -function resetfontsizes() - for k in (:titlefont, :guidefont, :tickfont, :legendfont) - resetfontsize(k) - end +"Resets font sizes to initial default values" +function scalefontsizes() + for k in (:titlefont, :guidefont, :tickfont, :legendfont) + f = default(k) + if haskey(_initial_fontsizes,k) + factor = f.pointsize / _initial_fontsizes[k].pointsize + scalefontsize(k, 1.0/factor) + end + end end "Wrap a string with font info" From 915c41c9d945ce845c77eeba2889f833464f4f69 Mon Sep 17 00:00:00 2001 From: Florian Oswald Date: Wed, 17 May 2017 17:48:03 +0200 Subject: [PATCH 125/720] addressed changes requested --- src/args.jl | 27 ++++----------------------- src/components.jl | 4 ++-- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/src/args.jl b/src/args.jl index f93aeae6..af791198 100644 --- a/src/args.jl +++ b/src/args.jl @@ -336,10 +336,10 @@ const _all_defaults = KW[ ] # to be able to reset font sizes to initial values -const _initial_fontsizes = Dict(:titlefont => deepcopy(_subplot_defaults[:titlefont]), - :legendfont => deepcopy(_subplot_defaults[:legendfont]), - :tickfont => deepcopy(_axis_defaults[:tickfont]), - :guidefont => deepcopy(_axis_defaults[:guidefont])) +const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefont].pointsize, + :legendfont => _subplot_defaults[:legendfont].pointsize, + :tickfont => _axis_defaults[:tickfont].pointsize, + :guidefont => _axis_defaults[:guidefont].pointsize) const _all_args = sort(collect(union(map(keys, _all_defaults)...))) @@ -525,25 +525,6 @@ function default(d::KW, k::Symbol) get(d, k, default(k)) end -# reset the defaults globally to values at startup - -""" -`initial(key)` returns the intial value for that key -""" - -function initial(k::Symbol) - k = get(_keyAliases, k, k) - for defaults in _all_initial_defaults - if haskey(defaults, k) - return defaults[k] - end - end - if haskey(_axis_initial_defaults, k) - return _axis_initial_defaults[k] - end - k in _suppress_warnings || error("Unknown key: ", k) -end - # ----------------------------------------------------------------------------- diff --git a/src/components.jl b/src/components.jl index 1f53f2d1..de3b1197 100644 --- a/src/components.jl +++ b/src/components.jl @@ -307,8 +307,8 @@ end function scalefontsizes() for k in (:titlefont, :guidefont, :tickfont, :legendfont) f = default(k) - if haskey(_initial_fontsizes,k) - factor = f.pointsize / _initial_fontsizes[k].pointsize + for k in keys(_initial_fontsizes) + factor = f.pointsize / _initial_fontsizes[k] scalefontsize(k, 1.0/factor) end end From 6cca7632849c218c122c934134b58588477be32f Mon Sep 17 00:00:00 2001 From: florian oswald Date: Wed, 17 May 2017 21:07:54 +0200 Subject: [PATCH 126/720] removed test for k --- src/components.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index de3b1197..efbe946e 100644 --- a/src/components.jl +++ b/src/components.jl @@ -307,7 +307,7 @@ end function scalefontsizes() for k in (:titlefont, :guidefont, :tickfont, :legendfont) f = default(k) - for k in keys(_initial_fontsizes) + if k in keys(_initial_fontsizes) factor = f.pointsize / _initial_fontsizes[k] scalefontsize(k, 1.0/factor) end From f09dfb703586da57fae07b8a9b1ee79a513fccb3 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 19 May 2017 07:56:36 -0700 Subject: [PATCH 127/720] Update REQUIRE --- REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/REQUIRE b/REQUIRE index 5875b39d..22f785ac 100644 --- a/REQUIRE +++ b/REQUIRE @@ -8,3 +8,4 @@ FixedSizeArrays Measures Showoff StatsBase 0.14.0 +JSON From b501c9bf4b55df2a0c2d818d45a0cd3b84129aeb Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Sat, 20 May 2017 15:39:26 -0700 Subject: [PATCH 128/720] fix world-age problem in PyPlot initialization --- src/backends/pyplot.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index df426bbb..7ba5b29c 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -84,10 +84,10 @@ function _initialize_backend(::PyPlotBackend) const pytransforms = PyPlot.pywrap(PyPlot.pyimport("matplotlib.transforms")) const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections")) const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d")) - end - # we don't want every command to update the figure - PyPlot.ioff() + # we don't want every command to update the figure + PyPlot.ioff() + end end # -------------------------------------------------------------------------------------- From 9abcba375360b13fce8102fc47a47173942b1ec2 Mon Sep 17 00:00:00 2001 From: Sheehan Olver Date: Sun, 21 May 2017 16:53:28 +1000 Subject: [PATCH 129/720] Fix plot(::Matrix{RGB{Float64}}) in plotly backend --- src/series.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index f7233c1a..f1ee5739 100644 --- a/src/series.jl +++ b/src/series.jl @@ -317,9 +317,10 @@ end # # images - colors @recipe function f{T<:Colorant}(mat::AMat{T}) + n, m = size(mat) + if is_seriestype_supported(:image) seriestype := :image - n, m = size(mat) SliceIt, 1:m, 1:n, Surface(mat) else seriestype := :heatmap From 08d7bee224b23a77f431d511a5d76674bee31cfd Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 21 May 2017 11:30:11 +0200 Subject: [PATCH 130/720] Remove conda update message These instructions led to installing a deprecated matplotlib version --- src/backends/pyplot.jl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 7ba5b29c..69fbe426 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -55,8 +55,6 @@ function add_backend_string(::PyPlotBackend) withenv("PYTHON" => "") do Pkg.build("PyPlot") end - import Conda - Conda.add("qt=4.8.5") # now restart julia! """ From e283c6557bae696db10501adabd14009a1b4815b Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 19 May 2017 16:43:52 +0200 Subject: [PATCH 131/720] Change default backends --- src/backends.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends.jl b/src/backends.jl index 779b91cc..8a124718 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -148,7 +148,7 @@ function pickDefaultBackend() # the ordering/inclusion of this package list is my semi-arbitrary guess at # which one someone will want to use if they have the package installed...accounting for # features, speed, and robustness - for pkgstr in ("PyPlot", "GR", "PlotlyJS", "Immerse", "Gadfly", "UnicodePlots") + for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVIsualize") if Pkg.installed(pkgstr) != nothing return backend(Symbol(lowercase(pkgstr))) end From bad2ef63c6c4794ee9be1525942667fcb6e2618d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 21 May 2017 23:44:12 +0200 Subject: [PATCH 132/720] fix passing ticks tuple on 0.6 --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 276d7374..8aaa1908 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -241,7 +241,7 @@ function get_ticks(axis::Axis) elseif typeof(ticks) <: Union{AVec, Int} # override ticks, but get the labels optimal_ticks_and_labels(axis, ticks) - elseif typeof(ticks) <: NTuple{2} + elseif typeof(ticks) <: NTuple{2, Any} # assuming we're passed (ticks, labels) ticks else From dd526e00ab74ed936ee15df24a1e26e8781d100a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 21 May 2017 23:47:26 +0200 Subject: [PATCH 133/720] undo: fix passing ticks tuple on 0.6 --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 8aaa1908..276d7374 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -241,7 +241,7 @@ function get_ticks(axis::Axis) elseif typeof(ticks) <: Union{AVec, Int} # override ticks, but get the labels optimal_ticks_and_labels(axis, ticks) - elseif typeof(ticks) <: NTuple{2, Any} + elseif typeof(ticks) <: NTuple{2} # assuming we're passed (ticks, labels) ticks else From ce169edd08f273ba62eaa197aea3f38797b33ed0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 21 May 2017 23:58:20 +0200 Subject: [PATCH 134/720] fix passing ticks tuple on 0.6 --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 9a39ca2e..a5882d9a 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -229,7 +229,7 @@ function get_ticks(axis::Axis) elseif typeof(ticks) <: AVec # override ticks, but get the labels optimal_ticks_and_labels(axis, ticks) - elseif typeof(ticks) <: NTuple{2} + elseif typeof(ticks) <: NTuple{2, Any} # assuming we're passed (ticks, labels) ticks else From a5482453ce7333847daa608e4f36649dcc07604d Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 23 May 2017 10:23:20 +0200 Subject: [PATCH 135/720] Replace `text` with `glvisualize_text` glvisualize defined a `text` function that shadowed a method of Plots exported `text` function --- src/backends/glvisualize.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f053dfb7..c0135a6c 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -692,7 +692,7 @@ function draw_ticks( text, positions, offsets end -function text(position, text, kw_args) +function glvisualize_textposition, text, kw_args) text_align = alignment2num(text.font) startpos = Vec2f0(position) atlas = GLVisualize.get_texture_atlas() @@ -769,7 +769,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive => true) extract_font(font, kw) t = PlotText(sp[:title], font) - push!(axis_vis, text(xy, t, kw)) + push!(axis_vis, glvisualize_textxy, t, kw)) end if xaxis[:guide] != "" tf = xaxis[:guidefont]; color = gl_color(xaxis[:foreground_color_guide]) @@ -778,7 +778,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive => true) t = PlotText(xaxis[:guide], font) extract_font(font, kw) - push!(axis_vis, text(xy, t, kw)) + push!(axis_vis, glvisualize_textxy, t, kw)) end if yaxis[:guide] != "" @@ -788,7 +788,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive=>true) t = PlotText(yaxis[:guide], font) extract_font(font, kw) - push!(axis_vis, text(xy, t, kw)) + push!(axis_vis, glvisualize_textxy, t, kw)) end axis_vis @@ -1167,7 +1167,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) txt_args = Dict{Symbol, Any}(:model => eye(GLAbstraction.Mat4f0)) x, y = Reactive.value(model_m) * Vec{4, Float32}(x, y, 0, 1) extract_font(font, txt_args) - t = text(Point2f0(x, y), PlotText(str, font), txt_args) + t = glvisualize_textPoint2f0(x, y), PlotText(str, font), txt_args) GLVisualize._view(t, sp_screen, camera = :perspective) end @@ -1479,7 +1479,7 @@ function make_label(sp, series, i) kw = Dict(:model => text_model(font, xy), :scale_primitive=>false) extract_font(font, kw) t = PlotText(labeltext, font) - push!(result, text(xy, t, kw)) + push!(result, glvisualize_textxy, t, kw)) GLAbstraction.Context(result...), i end From 53719e5a8ed6642066dd5e59598d4ce8cfe6875c Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 23 May 2017 10:51:00 +0200 Subject: [PATCH 136/720] Fix missing brackets --- src/backends/glvisualize.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index c0135a6c..e97d81fd 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -692,7 +692,7 @@ function draw_ticks( text, positions, offsets end -function glvisualize_textposition, text, kw_args) +function glvisualize_text(position, text, kw_args) text_align = alignment2num(text.font) startpos = Vec2f0(position) atlas = GLVisualize.get_texture_atlas() @@ -769,7 +769,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive => true) extract_font(font, kw) t = PlotText(sp[:title], font) - push!(axis_vis, glvisualize_textxy, t, kw)) + push!(axis_vis, glvisualize_text(xy, t, kw)) end if xaxis[:guide] != "" tf = xaxis[:guidefont]; color = gl_color(xaxis[:foreground_color_guide]) @@ -778,7 +778,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive => true) t = PlotText(xaxis[:guide], font) extract_font(font, kw) - push!(axis_vis, glvisualize_textxy, t, kw)) + push!(axis_vis, glvisualize_text(xy, t, kw)) end if yaxis[:guide] != "" @@ -788,7 +788,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are kw = Dict(:model => text_model(font, xy), :scale_primitive=>true) t = PlotText(yaxis[:guide], font) extract_font(font, kw) - push!(axis_vis, glvisualize_textxy, t, kw)) + push!(axis_vis, glvisualize_text(xy, t, kw)) end axis_vis @@ -1167,7 +1167,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) txt_args = Dict{Symbol, Any}(:model => eye(GLAbstraction.Mat4f0)) x, y = Reactive.value(model_m) * Vec{4, Float32}(x, y, 0, 1) extract_font(font, txt_args) - t = glvisualize_textPoint2f0(x, y), PlotText(str, font), txt_args) + t = glvisualize_text(Point2f0(x, y), PlotText(str, font), txt_args) GLVisualize._view(t, sp_screen, camera = :perspective) end @@ -1479,7 +1479,7 @@ function make_label(sp, series, i) kw = Dict(:model => text_model(font, xy), :scale_primitive=>false) extract_font(font, kw) t = PlotText(labeltext, font) - push!(result, glvisualize_textxy, t, kw)) + push!(result, glvisualize_text(xy, t, kw)) GLAbstraction.Context(result...), i end From 5439c3a3ce3c59e9e1cc159dd9e194e64946c8c1 Mon Sep 17 00:00:00 2001 From: lizz Date: Tue, 23 May 2017 21:41:31 +0800 Subject: [PATCH 137/720] Update backends.jl --- src/backends.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends.jl b/src/backends.jl index 8a124718..a402bc5f 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -148,7 +148,7 @@ function pickDefaultBackend() # the ordering/inclusion of this package list is my semi-arbitrary guess at # which one someone will want to use if they have the package installed...accounting for # features, speed, and robustness - for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVIsualize") + for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize") if Pkg.installed(pkgstr) != nothing return backend(Symbol(lowercase(pkgstr))) end From 5b73f1e56cae3d2d6f1431f01607337607b9ac72 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 23 May 2017 16:41:18 +0200 Subject: [PATCH 138/720] remove clean up code, switch to renderloop --- src/backends/glvisualize.jl | 42 ++----------------------------------- 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index e97d81fd..c28bfd31 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -98,41 +98,6 @@ end # end const _glplot_deletes = [] -function close_child_signals!(screen) - for child in screen.children - for (k, s) in child.inputs - empty!(s.actions) - end - for (k, cam) in child.cameras - for f in fieldnames(cam) - s = getfield(cam, f) - if isa(s, Signal) - close(s, false) - end - end - end - empty!(child.cameras) - close_child_signals!(child) - end - return -end -function empty_screen!(screen) - if isempty(_glplot_deletes) - close_child_signals!(screen) - empty!(screen) - empty!(screen.cameras) - for (k, s) in screen.inputs - empty!(s.actions) - end - empty!(screen) - else - for del_signal in _glplot_deletes - push!(del_signal, true) # trigger delete - end - empty!(_glplot_deletes) - end - nothing -end function get_plot_screen(list::Vector, name, result = []) for elem in list @@ -158,7 +123,7 @@ function create_window(plt::Plot{GLVisualizeBackend}, visible) resolution = plt[:size], visible = visible ) - @async GLWindow.waiting_renderloop(parent_screen) + @async GLWindow.renderloop(parent_screen) GLVisualize.add_screen(parent_screen) end # now lets get ourselves a permanent Plotting screen @@ -169,9 +134,6 @@ function create_window(plt::Plot{GLVisualizeBackend}, visible) parent, area = map(GLWindow.zeroposition, parent.area), name = name ) - for (k, s) in screen.inputs # copy signals, so we can clean them up better - screen.inputs[k] = map(identity, s) - end screen elseif length(plot_screens) == 1 plot_screens[1] @@ -181,7 +143,7 @@ function create_window(plt::Plot{GLVisualizeBackend}, visible) error("multiple Plot screens. Please don't use any screen with the name $name") end # Since we own this window, we can do deep cleansing - empty_screen!(screen) + empty!(screen) plt.o = screen GLWindow.set_visibility!(screen, visible) resize!(screen, plt[:size]...) From 4756e04e25586ff2bf55c9d46f5a924067baf5c4 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 24 May 2017 11:19:43 +0200 Subject: [PATCH 139/720] gr: improve viewport size for 3D plots --- src/backends/gr.jl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 697e2471..5f203c40 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -383,20 +383,28 @@ const viewport_plotarea = zeros(4) # the size of the current plot in pixels const gr_plot_size = zeros(2) -function gr_viewport_from_bbox(bb::BoundingBox, w, h, viewport_canvas) +function gr_viewport_from_bbox(sp::Subplot{GRBackend}, bb::BoundingBox, w, h, viewport_canvas) viewport = zeros(4) viewport[1] = viewport_canvas[2] * (left(bb) / w) viewport[2] = viewport_canvas[2] * (right(bb) / w) viewport[3] = viewport_canvas[4] * (1.0 - bottom(bb) / h) viewport[4] = viewport_canvas[4] * (1.0 - top(bb) / h) + if is3d(sp) + vp = viewport[:] + extent = min(vp[2] - vp[1], vp[4] - vp[3]) + viewport[1] = 0.5 * (vp[1] + vp[2] - extent) + viewport[2] = 0.5 * (vp[1] + vp[2] + extent) + viewport[3] = 0.5 * (vp[3] + vp[4] - extent) + viewport[4] = 0.5 * (vp[3] + vp[4] + extent) + end viewport end # change so we're focused on the viewport area function gr_set_viewport_cmap(sp::Subplot) GR.setviewport( - viewport_plotarea[2] + (is3d(sp) ? 0.04 : 0.02), - viewport_plotarea[2] + (is3d(sp) ? 0.07 : 0.05), + viewport_plotarea[2] + (is3d(sp) ? 0.07 : 0.02), + viewport_plotarea[2] + (is3d(sp) ? 0.10 : 0.05), viewport_plotarea[3], viewport_plotarea[4] ) @@ -506,8 +514,8 @@ end 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) + viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas) + viewport_plotarea[:] = gr_viewport_from_bbox(sp, plotarea(sp), w, h, viewport_canvas) # get data limits data_lims = gr_xy_axislims(sp) From effcffff8aa33d239dbec6d1a39444efe26806bb Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 26 May 2017 14:57:58 +0200 Subject: [PATCH 140/720] gr: corrected size of shape markers --- src/backends/gr.jl | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 5f203c40..fdaa6edc 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -277,10 +277,11 @@ function gr_draw_marker(xi, yi, msize, shape::Shape) sx, sy = coords(shape) # convert to ndc coords (percentages of window) GR.selntran(0) + w, h = gr_plot_size + f = msize / (w + h) xi, yi = GR.wctondc(xi, yi) - ms_ndc_x, ms_ndc_y = gr_pixels_to_ndc(msize, msize) - GR.fillarea(xi .+ sx .* ms_ndc_x, - yi .+ sy .* ms_ndc_y) + GR.fillarea(xi .+ sx .* f, + yi .+ sy .* f) GR.selntran(1) end @@ -442,15 +443,6 @@ end gr_view_xcenter() = 0.5 * (viewport_plotarea[1] + viewport_plotarea[2]) gr_view_ycenter() = 0.5 * (viewport_plotarea[3] + viewport_plotarea[4]) -gr_view_xdiff() = viewport_plotarea[2] - viewport_plotarea[1] -gr_view_ydiff() = viewport_plotarea[4] - viewport_plotarea[3] - -function gr_pixels_to_ndc(x_pixels, y_pixels) - w,h = gr_plot_size - totx = w * gr_view_xdiff() - toty = h * gr_view_ydiff() - x_pixels / totx, y_pixels / toty -end # -------------------------------------------------------------------------------------- @@ -512,6 +504,11 @@ function gr_display(plt::Plot) end +function _update_min_padding!(sp::Subplot{GRBackend}) + sp.minpad = (10mm,2mm,2mm,8mm) +end + + function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # the viewports for this subplot viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas) @@ -699,19 +696,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_text(xi + (mirror ? 1 : -1) * 2e-3, yi, string(dv)) end end - - # window_diag = sqrt(gr_view_xdiff()^2 + gr_view_ydiff()^2) - # ticksize = 0.0075 * window_diag - # if outside_ticks - # ticksize = -ticksize - # end - # # TODO: this should be done for each axis separately - # gr_set_linecolor(xaxis[:foreground_color_axis]) - - # x1, x2 = xaxis[:flip] ? (xmax,xmin) : (xmin,xmax) - # y1, y2 = yaxis[:flip] ? (ymax,ymin) : (ymin,ymax) - # GR.axes(xtick, ytick, x1, y1, 1, 1, ticksize) - # GR.axes(xtick, ytick, x2, y2, -1, -1, -ticksize) end # end From d6f1120dfc5480549e47de5b4e60e3d77dc20f1d Mon Sep 17 00:00:00 2001 From: wgrant Date: Sat, 27 May 2017 16:19:25 +1000 Subject: [PATCH 141/720] add ability to specify legend placement to gr backend --- src/backends/gr.jl | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index fdaa6edc..6cdd85b1 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -444,6 +444,34 @@ end gr_view_xcenter() = 0.5 * (viewport_plotarea[1] + viewport_plotarea[2]) gr_view_ycenter() = 0.5 * (viewport_plotarea[3] + viewport_plotarea[4]) +function gr_legend_pos(s::Symbol,w,h) + str = string(s) + println(str) + if str == "best" + str = "topright" + end + if contains(str,"right") + xpos = viewport_plotarea[2] - 0.05 - w + elseif contains(str,"left") + xpos = viewport_plotarea[1] + 0.11 + else + xpos = (viewport_plotarea[2]-viewport_plotarea[1])/2 - w/2 +.04 + end + if contains(str,"top") + ypos = viewport_plotarea[4] - 0.06 + elseif contains(str,"bottom") + ypos = viewport_plotarea[3] + h + 0.06 + else + ypos = (viewport_plotarea[4]-viewport_plotarea[3])/2 + h/2 + end + (xpos,ypos) +end + +function gr_legend_pos{S<:Real, T<:Real}(v::Tuple{S,T},w,h) + xpos = v[1] * (viewport_plotarea[2] - viewport_plotarea[1]) + viewport_plotarea[1] + ypos = v[2] * (viewport_plotarea[4] - viewport_plotarea[3]) + viewport_plotarea[3] + (xpos,ypos) +end # -------------------------------------------------------------------------------------- @@ -989,9 +1017,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) w = max(w, tbx[3] - tbx[1]) end if w > 0 - xpos = viewport_plotarea[2] - 0.05 - w - ypos = viewport_plotarea[4] - 0.06 dy = _gr_point_mult[1] * sp[:legendfont].pointsize * 1.75 + h = dy*n + (xpos,ypos) = gr_legend_pos(sp[:legend],w,h) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_set_fillcolor(sp[:background_color_legend]) GR.fillrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n) From 231e11715fea166474c46cc24fea2421afdb000d Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Sun, 28 May 2017 16:23:21 +0200 Subject: [PATCH 142/720] gr: fix problems with axes display --- src/backends/gr.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index fdaa6edc..d2e34390 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -661,7 +661,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # spine (border) and tick marks gr_set_line(1, :solid, sp[:xaxis][:foreground_color_axis]) + GR.setclip(0) gr_polyline(coords(spine_segs)...) + GR.setclip(1) if !(xticks in (nothing, false)) # x labels @@ -676,7 +678,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - gr_text(xi, yi + (mirror ? 1 : -1) * 2e-3, string(dv)) + gr_text(xi, yi + (mirror ? 1 : -1) * 1e-2, string(dv)) end end @@ -693,7 +695,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc((flip $ mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi - gr_text(xi + (mirror ? 1 : -1) * 2e-3, yi, string(dv)) + gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) end end end From abf8ca2dc7bbc25c843a433c58570d546f8ba34e Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 30 May 2017 10:25:45 +0200 Subject: [PATCH 143/720] gr: fixed several bugs - use correct image orientation - added missing marker keywords - improved alignment of axes labels - corrected scaling of polar coordinates - slightly shrink pie chart viewport --- src/backends/gr.jl | 8 +++++--- src/utils.jl | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d2e34390..9958e0a5 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -76,6 +76,8 @@ const gr_markertype = KW( :diamond => -13, :utriangle => -3, :dtriangle => -5, + :ltriangle => -18, + :rtriangle => -17, :pentagon => -21, :hexagon => -22, :heptagon => -23, @@ -678,7 +680,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - gr_text(xi, yi + (mirror ? 1 : -1) * 1e-2, string(dv)) + gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3, string(dv)) end end @@ -880,7 +882,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.selntran(0) GR.setfillintstyle(GR.INTSTYLE_SOLID) xmin, xmax, ymin, ymax = viewport_plotarea - ymax -= 0.05 * (xmax - xmin) + ymax -= 0.1 * (xmax - xmin) xcenter = 0.5 * (xmin + xmax) ycenter = 0.5 * (ymin + ymax) if xmax - xmin > ymax - ymin @@ -944,7 +946,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :image - z = transpose_z(series, series[:z].surf, true) + z = transpose_z(series, series[:z].surf, true)' w, h = size(z) if eltype(z) <: Colors.AbstractGray grey = round(UInt8, float(z) * 255) diff --git a/src/utils.jl b/src/utils.jl index da1d1cb6..f5ae3733 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -350,7 +350,7 @@ end function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) rmin, rmax = r_extrema phi, r = x, y - r = 0.5 * (r - rmin) / (rmax - rmin) + r = (r - rmin) / (rmax - rmin) n = max(length(phi), length(r)) x = zeros(n) y = zeros(n) From 6e8bfe1ea6ba0fd9717c4b8f8131001ce5743f2e Mon Sep 17 00:00:00 2001 From: Oliver Schulz Date: Wed, 31 May 2017 23:04:39 +0200 Subject: [PATCH 144/720] Remove remnant debug output about binning --- src/recipes.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 1bc4cad5..d3fe10fa 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -589,7 +589,6 @@ _hist_norm_mode(mode::Symbol) = mode _hist_norm_mode(mode::Bool) = mode ? :pdf : :none function _make_hist{N}(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) - info("binning = $binning") edges = _hist_edges(vs, binning) h = float( weights == nothing ? StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) : From 0e308d9f502b37bfd9aa469858c2070aa6fe6103 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 1 Jun 2017 11:55:43 +0200 Subject: [PATCH 145/720] Change installation message --- src/backends/glvisualize.jl | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index c28bfd31..b1f5663c 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -77,14 +77,9 @@ end function add_backend_string(b::GLVisualizeBackend) """ - For those incredibly brave souls who assume full responsibility for what happens next... - There's an easy way to get what you need for the GLVisualize backend to work (until Pkg3 is usable): - - Pkg.clone("https://github.com/tbreloff/MetaPkg.jl") - using MetaPkg - meta_checkout("MetaGL") - - See the MetaPkg readme for details... + if !Plots.is_installed("GLVisualize") + Pkg.add("PyPlot") + end """ end From 84406f0823132acfb109251295d2ab6e0d803675 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Thu, 1 Jun 2017 17:10:03 +0200 Subject: [PATCH 146/720] Fixed writing error. --- src/backends/glvisualize.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index b1f5663c..f5168e16 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -78,7 +78,7 @@ end function add_backend_string(b::GLVisualizeBackend) """ if !Plots.is_installed("GLVisualize") - Pkg.add("PyPlot") + Pkg.add("GLVisualize") end """ end From d29df4289e011506743c99f5eec3f05f1bf242d3 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Thu, 1 Jun 2017 19:17:28 +0200 Subject: [PATCH 147/720] RFC: Ignore NaNs on 0.6 (like on 0.5): fixes #796 (#876) Replaces min, max, minimum, mean, maximum and extrema with NaNMath versions in places where NaNs can occur. To avoid returning NaN when there are NaNs in the Vector * Also add maximum and minimum * define _-prefaced versions of mean, maximum, minimum, extrema * variable arg numbers for Base methods * Different implementation of the override * remove underscore from 2-arg versions of maximum * some forgotten extrema -> _extrema * Fix bug in _extrema definition * edit comment * replace min and max with _min and _max * Base NaN-compliant functions on NaNMath replace _min and _max with NaNMath versions * Use NaNMath explicitly everywhere * remove unneccesary NaNMath calls * Ensure ceil does not error on NaN * Added one more maximum in gr --- REQUIRE | 1 + src/Plots.jl | 1 + src/axes.jl | 22 +++++++++++----------- src/backends/glvisualize.jl | 20 ++++++++++---------- src/backends/gr.jl | 8 ++++---- src/backends/inspectdr.jl | 2 +- src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 12 ++++++------ src/components.jl | 8 ++++---- src/layouts.jl | 2 +- src/pipeline.jl | 2 +- src/recipes.jl | 22 +++++++++++----------- src/utils.jl | 28 ++++++++++++++-------------- test/runtests.jl | 4 ++-- 14 files changed, 68 insertions(+), 66 deletions(-) diff --git a/REQUIRE b/REQUIRE index 22f785ac..2f70e7f9 100644 --- a/REQUIRE +++ b/REQUIRE @@ -9,3 +9,4 @@ Measures Showoff StatsBase 0.14.0 JSON +NaNMath diff --git a/src/Plots.jl b/src/Plots.jl index 7e630ad7..4842a039 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -10,6 +10,7 @@ using Base.Meta @reexport using PlotThemes import Showoff import StatsBase +import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563 export grid, diff --git a/src/axes.jl b/src/axes.jl index a5882d9a..0d855190 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -118,7 +118,7 @@ Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true) # Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k) Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...) Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k) -Base.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) +NaNMath.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) const _scale_funcs = Dict{Symbol,Function}( @@ -260,8 +260,8 @@ end function expand_extrema!(ex::Extrema, v::Number) - ex.emin = min(v, ex.emin) - ex.emax = max(v, ex.emax) + ex.emin = NaNMath.min(v, ex.emin) + ex.emax = NaNMath.max(v, ex.emax) ex end @@ -276,8 +276,8 @@ expand_extrema!(axis::Axis, ::Bool) = axis[:extrema] function expand_extrema!{MIN<:Number,MAX<:Number}(axis::Axis, v::Tuple{MIN,MAX}) ex = axis[:extrema] - ex.emin = min(v[1], ex.emin) - ex.emax = max(v[2], ex.emax) + ex.emin = NaNMath.min(v[1], ex.emin) + ex.emax = NaNMath.max(v[2], ex.emax) ex end function expand_extrema!{N<:Number}(axis::Axis, v::AVec{N}) @@ -349,11 +349,11 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = mean(diff(data)) + bw = d[:bar_width] = NaNMath.mean(diff(data)) end axis = sp.attr[Symbol(dsym, :axis)] - expand_extrema!(axis, maximum(data) + 0.5maximum(bw)) - expand_extrema!(axis, minimum(data) - 0.5minimum(bw)) + expand_extrema!(axis, NaNMath.maximum(data) + 0.5maximum(bw)) + expand_extrema!(axis, NaNMath.minimum(data) - 0.5minimum(bw)) end end @@ -368,8 +368,8 @@ end # push the limits out slightly function widen(lmin, lmax) span = lmax - lmin - # eps = max(1e-16, min(1e-2span, 1e-10)) - eps = max(1e-16, 0.03span) + # eps = NaNMath.max(1e-16, min(1e-2span, 1e-10)) + eps = NaNMath.max(1e-16, 0.03span) lmin-eps, lmax+eps end @@ -425,7 +425,7 @@ function discrete_value!(axis::Axis, dv) # @show axis[:discrete_map], axis[:discrete_values], dv if cv_idx == -1 ex = axis[:extrema] - cv = max(0.5, ex.emax + 1.0) + cv = NaNMath.max(0.5, ex.emax + 1.0) expand_extrema!(axis, cv) push!(axis[:discrete_values], dv) push!(axis[:continuous_values], cv) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f5168e16..c09fcab0 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -304,7 +304,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y])) end end else @@ -315,7 +315,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y])) else error("Unsupported limits: $clims") end @@ -367,14 +367,14 @@ end dist(a, b) = abs(a-b) -mindist(x, a, b) = min(dist(a, x), dist(b, x)) +mindist(x, a, b) = NaNMath.min(dist(a, x), dist(b, x)) function gappy(x, ps) n = length(ps) x <= first(ps) && return first(ps) - x for j=1:(n-1) p0 = ps[j] - p1 = ps[min(j+1, n)] + p1 = ps[NaNMath.min(j+1, n)] if p0 <= x && p1 >= x return mindist(x, p0, p1) * (isodd(j) ? 1 : -1) end @@ -482,7 +482,7 @@ function hover(to_hover, to_display, window) end function extract_extrema(d, kw_args) - xmin, xmax = extrema(d[:x]); ymin, ymax = extrema(d[:y]) + xmin, xmax = NaNMath.extrema(d[:x]); ymin, ymax = NaNMath.extrema(d[:y]) kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(xmin, ymin, xmax-xmin, ymax-ymin) nothing end @@ -509,7 +509,7 @@ function extract_colornorm(d, kw_args) else d[:y] end - kw_args[:color_norm] = Vec2f0(extrema(z)) + kw_args[:color_norm] = Vec2f0(NaNMath.extrema(z)) kw_args[:intensity] = map(Float32, collect(z)) end end @@ -781,7 +781,7 @@ function gl_bar(d, kw_args) # compute half-width of bars bw = nothing hw = if bw == nothing - mean(diff(x)) + NaNMath.mean(diff(x)) else Float64[cycle(bw,i)*0.5 for i=1:length(x)] end @@ -864,7 +864,7 @@ function gl_boxplot(d, kw_args) end # change q1 and q5 to show outliers # using maximum and minimum values inside the limits - q1, q5 = extrema(inside) + q1, q5 = NaNMath.extrema(inside) end # Box if notch @@ -1318,7 +1318,7 @@ function gl_contour(x, y, z, kw_args) T = eltype(z) levels = Contour.contours(map(T, x), map(T, y), z, h) result = Point2f0[] - zmin, zmax = get(kw_args, :limits, Vec2f0(extrema(z))) + zmin, zmax = get(kw_args, :limits, Vec2f0(NaNMath.extrema(z))) cmap = get(kw_args, :color_map, get(kw_args, :color, RGBA{Float32}(0,0,0,1))) colors = RGBA{Float32}[] for c in levels.contours @@ -1339,7 +1339,7 @@ end function gl_heatmap(x,y,z, kw_args) - get!(kw_args, :color_norm, Vec2f0(extrema(z))) + get!(kw_args, :color_norm, Vec2f0(NaNMath.extrema(z))) get!(kw_args, :color_map, Plots.make_gradient(cgrad())) delete!(kw_args, :intensity) I = GLVisualize.Intensity{1, Float32} diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9958e0a5..0c34b5d4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -264,7 +264,7 @@ end normalize_zvals(zv::Void) = zv function normalize_zvals(zv::AVec) - vmin, vmax = extrema(zv) + vmin, vmax = NaNMath.extrema(zv) if vmin == vmax zeros(length(zv)) else @@ -428,7 +428,7 @@ function gr_set_viewport_polar() ymax -= 0.05 * (xmax - xmin) xcenter = 0.5 * (xmin + xmax) ycenter = 0.5 * (ymin + ymax) - r = 0.5 * min(xmax - xmin, ymax - ymin) + r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin) GR.setviewport(xcenter -r, xcenter + r, ycenter - r, ycenter + r) GR.setwindow(-1, 1, -1, 1) r @@ -639,7 +639,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif ispolar(sp) r = gr_set_viewport_polar() - rmin, rmax = GR.adjustrange(minimum(r), maximum(r)) + rmin, rmax = GR.adjustrange(NaNMath.minimum(r), NaNMath.maximum(r)) # rmin, rmax = axis_limits(sp[:yaxis]) gr_polaraxes(rmin, rmax) @@ -824,7 +824,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # create the colorbar of contour levels if sp[:colorbar] != :none gr_set_viewport_cmap(sp) - l = round(Int32, 1000 + (h - minimum(h)) / (maximum(h) - minimum(h)) * 255) + l = round(Int32, 1000 + (h - NaNMath.minimum(h)) / (NaNMath.maximum(h) - NaNMath.minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index c58ef884..18b5b541 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -349,7 +349,7 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) 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)) + rmax = NaNMath.max(abs(ymin), abs(ymax)) xmin, xmax = -rmax, rmax ymin, ymax = -rmax, rmax end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 814e4775..9232fb85 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -546,7 +546,7 @@ function plotly_series(plt::Plot, series::Series) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) grad = as_gradient(series[:markercolor], series[:markeralpha]) - zmin, zmax = extrema(series[:marker_z]) + zmin, zmax = NaNMath.extrema(series[:marker_z]) zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) [rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]] end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 69fbe426..49760a75 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -705,11 +705,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # contours on the axis planes if series[:contours] for (zdir,mat) in (("x",x), ("y",y), ("z",z)) - offset = (zdir == "y" ? maximum : minimum)(mat) + offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat) handle = ax[:contourf](x, y, z, levelargs...; zdir = zdir, cmap = py_fillcolormap(series), - offset = (zdir == "y" ? maximum : minimum)(mat) # where to draw the contour plane + offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat) # where to draw the contour plane ) push!(handles, handle) needs_colorbar = true @@ -778,7 +778,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end clims = sp[:clims] - zmin, zmax = extrema(z) + zmin, zmax = NaNMath.extrema(z) extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax @@ -926,14 +926,14 @@ function py_compute_axis_minval(axis::Axis) for series in series_list(sp) v = series.d[axis[:letter]] if !isempty(v) - minval = min(minval, minimum(abs(v))) + minval = NaNMath.min(minval, NaNMath.minimum(abs(v))) end end end # now if the axis limits go to a smaller abs value, use that instead vmin, vmax = axis_limits(axis) - minval = min(minval, abs(vmin), abs(vmax)) + minval = NaNMath.min(minval, abs(vmin), abs(vmax)) minval end @@ -954,7 +954,7 @@ function py_set_scale(ax, axis::Axis) elseif scale == :log10 10 end - kw[Symbol(:linthresh,letter)] = max(1e-16, py_compute_axis_minval(axis)) + kw[Symbol(:linthresh,letter)] = NaNMath.max(1e-16, py_compute_axis_minval(axis)) "symlog" end func(arg; kw...) diff --git a/src/components.jl b/src/components.jl index b20eb3d0..4a11bd7e 100644 --- a/src/components.jl +++ b/src/components.jl @@ -501,7 +501,7 @@ immutable ZValues zrange::Tuple{Float64,Float64} end -function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (minimum(values), maximum(values))) +function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (NaNMath.minimum(values), NaNMath.maximum(values))) ZValues(collect(float(values)), map(Float64, zrange)) end @@ -645,8 +645,8 @@ function (bc::BezierCurve)(t::Real) p end -Base.mean(x::Real, y::Real) = 0.5*(x+y) -Base.mean{N,T<:Real}(ps::FixedSizeArrays.Vec{N,T}...) = sum(ps) / length(ps) +# mean(x::Real, y::Real) = 0.5*(x+y) #commented out as I cannot see this used anywhere and it overwrites a Base method with different functionality +# mean{N,T<:Real}(ps::FixedSizeArrays.Vec{N,T}...) = sum(ps) / length(ps) # I also could not see this used anywhere, and it's type piracy - implementing a NaNMath version for this would just involve converting to a standard array @deprecate curve_points coords @@ -659,7 +659,7 @@ function directed_curve(args...; kw...) end function extrema_plus_buffer(v, buffmult = 0.2) - vmin,vmax = extrema(v) + vmin,vmax = NaNMath.extrema(v) vdiff = vmax-vmin buffer = vdiff * buffmult vmin - buffer, vmax + buffer diff --git a/src/layouts.jl b/src/layouts.jl index a5814ba1..003c63c1 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -704,7 +704,7 @@ function link_axes!(axes::Axis...) a1 = axes[1] for i=2:length(axes) a2 = axes[i] - expand_extrema!(a1, extrema(a2)) + expand_extrema!(a1, NaNMath.extrema(a2)) for k in (:extrema, :discrete_values, :continuous_values, :discrete_map) a2[k] = a1[k] end diff --git a/src/pipeline.jl b/src/pipeline.jl index 70644055..3a68e4a4 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -153,7 +153,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::KW) if get(kw, :smooth, false) x, y = kw[:x], kw[:y] β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) - sx = [minimum(x), maximum(x)] + sx = [NaNMath.minimum(x), NaNMath.maximum(x)] sy = β * sx + α push!(kw_list, merge(copy(kw), KW( :seriestype => :path, diff --git a/src/recipes.jl b/src/recipes.jl index d3fe10fa..68ffd407 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -225,7 +225,7 @@ end fr = if yaxis[:scale] == :identity 0.0 else - min(axis_limits(yaxis)[1], minimum(y)) + NaNMath.min(axis_limits(yaxis)[1], NaNMath.minimum(y)) end end newx, newy = zeros(3n), zeros(3n) @@ -338,7 +338,7 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5mean(diff(procx)) + 0.5NaNMath.mean(diff(procx)) else Float64[0.5cycle(bw,i) for i=1:length(procx)] end @@ -366,7 +366,7 @@ end end # widen limits out a bit - expand_extrema!(axis, widen(extrema(xseg.pts)...)) + expand_extrema!(axis, widen(NaNMath.extrema(xseg.pts)...)) # switch back if !isvertical(d) @@ -414,8 +414,8 @@ end function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) w_adj = _scale_adjusted_values(T, w, wscale) - w_min = minimum(w_adj) - w_max = maximum(w_adj) + w_min = NaNMath.minimum(w_adj) + w_max = NaNMath.maximum(w_adj) baseline = _binbarlike_baseline(w_min, wscale) w_adj, baseline end @@ -548,9 +548,9 @@ Plots.@deps stepbins path function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) - _cl(x) = max(ceil(Int, x), 1) + _cl(x) = ceil(Int, NaNMath.max(x, one(x))) _iqr(v) = quantile(v, 0.75) - quantile(v, 0.25) - _span(v) = maximum(v) - minimum(v) + _span(v) = NaNMath.maximum(v) - NaNMath.minimum(v) n_samples = length(linearindices(first(vs))) # Estimator for number of samples in one row/column of bins along each axis: @@ -919,7 +919,7 @@ end # get the joined vector function get_xy(v::AVec{OHLC}, x = 1:length(v)) - xdiff = 0.3mean(abs(diff(x))) + xdiff = 0.3NaNMath.mean(abs(diff(x))) x_out, y_out = zeros(0), zeros(0) for (i,ohlc) in enumerate(v) ox,oy = get_xy(ohlc, x[i], xdiff) @@ -984,8 +984,8 @@ end yflip := true aspect_ratio := 1 rs, cs, zs = findnz(z.surf) - xlim := extrema(cs) - ylim := extrema(rs) + xlim := NaNMath.extrema(cs) + ylim := NaNMath.extrema(rs) if d[:markershape] == :none markershape := :circle end @@ -1006,7 +1006,7 @@ end "Adds a+bx... straight line over the current plot" function abline!(plt::Plot, a, b; kw...) - plot!(plt, [extrema(plt)...], x -> b + a*x; kw...) + plot!(plt, [NaNMath.extrema(plt)...], x -> b + a*x; kw...) end abline!(args...; kw...) = abline!(current(), args...; kw...) diff --git a/src/utils.jl b/src/utils.jl index f5ae3733..dddfdf19 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -3,7 +3,7 @@ calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for "Make histogram-like bins of data" function binData(data, nbins) - lo, hi = extrema(data) + lo, hi = NaNMath.extrema(data) edges = collect(linspace(lo, hi, nbins+1)) midpoints = calcMidpoints(edges) buckets = Int[max(2, min(searchsortedfirst(edges, x), length(edges)))-1 for x in data] @@ -109,7 +109,7 @@ function regressionXY(x, y) β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) # make a line segment - regx = [minimum(x), maximum(x)] + regx = [NaNMath.minimum(x), NaNMath.maximum(x)] regy = β * regx + α regx, regy end @@ -283,9 +283,9 @@ unzip{T}(xyuv::FixedSizeArrays.Vec{4,T}) = T[xyuv[1]], T[xyuv[2]], T[xyuv[ # given 2-element lims and a vector of data x, widen lims to account for the extrema of x function _expand_limits(lims, x) try - e1, e2 = extrema(x) - lims[1] = min(lims[1], e1) - lims[2] = max(lims[2], e2) + e1, e2 = NaNMath.extrema(x) + lims[1] = NaNMath.min(lims[1], e1) + lims[2] = NaNMath.max(lims[2], e2) # catch err # warn(err) end @@ -334,17 +334,17 @@ sortedkeys(d::Dict) = sort(collect(keys(d))) "create an (n+1) list of the outsides of heatmap rectangles" function heatmap_edges(v::AVec) - vmin, vmax = extrema(v) + vmin, vmax = NaNMath.extrema(v) extra = 0.5 * (vmax-vmin) / (length(v)-1) vcat(vmin-extra, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra) end function calc_r_extrema(x, y) - xmin, xmax = extrema(x) - ymin, ymax = extrema(y) - r = 0.5 * min(xmax - xmin, ymax - ymin) - extrema(r) + xmin, xmax = NaNMath.extrema(x) + ymin, ymax = NaNMath.extrema(y) + r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin) + NaNMath.extrema(r) end function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) @@ -645,7 +645,7 @@ end # used in updating an existing series extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n) -extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + maximum(v)) +extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + NaNMath.maximum(v)) extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v) @@ -871,9 +871,9 @@ mm2px(mm::Real) = float(px / MM_PER_PX) "Smallest x in plot" -xmin(plt::Plot) = minimum([minimum(series.d[:x]) for series in plt.series_list]) +xmin(plt::Plot) = NaNMath.minimum([NaNMath.minimum(series.d[:x]) for series in plt.series_list]) "Largest x in plot" -xmax(plt::Plot) = maximum([maximum(series.d[:x]) for series in plt.series_list]) +xmax(plt::Plot) = NaNMath.maximum([NaNMath.maximum(series.d[:x]) for series in plt.series_list]) "Extrema of x-values in plot" -Base.extrema(plt::Plot) = (xmin(plt), xmax(plt)) +NaNMath.extrema(plt::Plot) = (xmin(plt), xmax(plt)) diff --git a/test/runtests.jl b/test/runtests.jl index 94f95a1b..d7d4441c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -78,12 +78,12 @@ facts("Axes") do @fact typeof(axis) --> Plots.Axis @fact Plots.discrete_value!(axis, "HI") --> (0.5, 1) @fact Plots.discrete_value!(axis, :yo) --> (1.5, 2) - @fact extrema(axis) --> (0.5,1.5) + @fact Plots.NaNMath.extrema(axis) --> (0.5,1.5) @fact axis[:discrete_map] --> Dict{Any,Any}(:yo => 2, "HI" => 1) Plots.discrete_value!(axis, ["x$i" for i=1:5]) Plots.discrete_value!(axis, ["x$i" for i=0:2]) - @fact extrema(axis) --> (0.5, 7.5) + @fact Plots.NaNMath.extrema(axis) --> (0.5, 7.5) end From 80d0d6ecc88e91c74982fbcc8cfdd5c149e12f7f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 1 Jun 2017 22:19:38 +0200 Subject: [PATCH 148/720] Change NaNMath implementation We needed some functions to forward to Base methods, e.g. when non-`AbstractArray{<:AbstractFloat}` was passed --- src/Plots.jl | 13 ++++++++++++- src/axes.jl | 8 ++++---- src/backends/glvisualize.jl | 16 ++++++++-------- src/backends/gr.jl | 6 +++--- src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 8 ++++---- src/components.jl | 4 ++-- src/layouts.jl | 2 +- src/pipeline.jl | 2 +- src/recipes.jl | 20 ++++++++++---------- src/utils.jl | 22 +++++++++++----------- test/runtests.jl | 4 ++-- 12 files changed, 59 insertions(+), 48 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 4842a039..c990e8be 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -10,7 +10,6 @@ using Base.Meta @reexport using PlotThemes import Showoff import StatsBase -import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563 export grid, @@ -107,6 +106,18 @@ export # --------------------------------------------------------- +import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563 +ignoreNaN_minimum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.minimum(x) +ignoreNaN_minimum(x) = Base.minimum(x) +ignoreNaN_maximum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.maximum(x) +ignoreNaN_maximum(x) = Base.maximum(x) +ignoreNaN_mean{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.mean(x) +ignoreNaN_mean(x) = Base.mean(x) +ignoreNaN_extrema{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.extrema(x) +ignoreNaN_extrema(x) = Base.extrema(x) + +# --------------------------------------------------------- + import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox diff --git a/src/axes.jl b/src/axes.jl index 0d855190..f629d22c 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -118,7 +118,7 @@ Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true) # Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k) Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...) Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k) -NaNMath.extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) +ignoreNaN_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) const _scale_funcs = Dict{Symbol,Function}( @@ -349,11 +349,11 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = NaNMath.mean(diff(data)) + bw = d[:bar_width] = ignoreNaN_mean(diff(data)) end axis = sp.attr[Symbol(dsym, :axis)] - expand_extrema!(axis, NaNMath.maximum(data) + 0.5maximum(bw)) - expand_extrema!(axis, NaNMath.minimum(data) - 0.5minimum(bw)) + expand_extrema!(axis, ignoreNaN_maximum(data) + 0.5maximum(bw)) + expand_extrema!(axis, ignoreNaN_minimum(data) - 0.5minimum(bw)) end end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index c09fcab0..5e78c046 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -304,7 +304,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y])) end end else @@ -315,7 +315,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(NaNMath.extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y])) else error("Unsupported limits: $clims") end @@ -482,7 +482,7 @@ function hover(to_hover, to_display, window) end function extract_extrema(d, kw_args) - xmin, xmax = NaNMath.extrema(d[:x]); ymin, ymax = NaNMath.extrema(d[:y]) + xmin, xmax = ignoreNaN_extrema(d[:x]); ymin, ymax = ignoreNaN_extrema(d[:y]) kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(xmin, ymin, xmax-xmin, ymax-ymin) nothing end @@ -509,7 +509,7 @@ function extract_colornorm(d, kw_args) else d[:y] end - kw_args[:color_norm] = Vec2f0(NaNMath.extrema(z)) + kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(z)) kw_args[:intensity] = map(Float32, collect(z)) end end @@ -781,7 +781,7 @@ function gl_bar(d, kw_args) # compute half-width of bars bw = nothing hw = if bw == nothing - NaNMath.mean(diff(x)) + ignoreNaN_mean(diff(x)) else Float64[cycle(bw,i)*0.5 for i=1:length(x)] end @@ -864,7 +864,7 @@ function gl_boxplot(d, kw_args) end # change q1 and q5 to show outliers # using maximum and minimum values inside the limits - q1, q5 = NaNMath.extrema(inside) + q1, q5 = ignoreNaN_extrema(inside) end # Box if notch @@ -1318,7 +1318,7 @@ function gl_contour(x, y, z, kw_args) T = eltype(z) levels = Contour.contours(map(T, x), map(T, y), z, h) result = Point2f0[] - zmin, zmax = get(kw_args, :limits, Vec2f0(NaNMath.extrema(z))) + zmin, zmax = get(kw_args, :limits, Vec2f0(ignoreNaN_extrema(z))) cmap = get(kw_args, :color_map, get(kw_args, :color, RGBA{Float32}(0,0,0,1))) colors = RGBA{Float32}[] for c in levels.contours @@ -1339,7 +1339,7 @@ end function gl_heatmap(x,y,z, kw_args) - get!(kw_args, :color_norm, Vec2f0(NaNMath.extrema(z))) + get!(kw_args, :color_norm, Vec2f0(ignoreNaN_extrema(z))) get!(kw_args, :color_map, Plots.make_gradient(cgrad())) delete!(kw_args, :intensity) I = GLVisualize.Intensity{1, Float32} diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0c34b5d4..af02902b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -264,7 +264,7 @@ end normalize_zvals(zv::Void) = zv function normalize_zvals(zv::AVec) - vmin, vmax = NaNMath.extrema(zv) + vmin, vmax = ignoreNaN_extrema(zv) if vmin == vmax zeros(length(zv)) else @@ -639,7 +639,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif ispolar(sp) r = gr_set_viewport_polar() - rmin, rmax = GR.adjustrange(NaNMath.minimum(r), NaNMath.maximum(r)) + rmin, rmax = GR.adjustrange(ignoreNaN_minimum(r), ignoreNaN_maximum(r)) # rmin, rmax = axis_limits(sp[:yaxis]) gr_polaraxes(rmin, rmax) @@ -824,7 +824,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # create the colorbar of contour levels if sp[:colorbar] != :none gr_set_viewport_cmap(sp) - l = round(Int32, 1000 + (h - NaNMath.minimum(h)) / (NaNMath.maximum(h) - NaNMath.minimum(h)) * 255) + l = round(Int32, 1000 + (h - ignoreNaN_minimum(h)) / (ignoreNaN_maximum(h) - ignoreNaN_minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9232fb85..3b681618 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -546,7 +546,7 @@ function plotly_series(plt::Plot, series::Series) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) grad = as_gradient(series[:markercolor], series[:markeralpha]) - zmin, zmax = NaNMath.extrema(series[:marker_z]) + zmin, zmax = ignoreNaN_extrema(series[:marker_z]) zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) [rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]] end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 49760a75..82237fbb 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -705,11 +705,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # contours on the axis planes if series[:contours] for (zdir,mat) in (("x",x), ("y",y), ("z",z)) - offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat) + offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat) handle = ax[:contourf](x, y, z, levelargs...; zdir = zdir, cmap = py_fillcolormap(series), - offset = (zdir == "y" ? NaNMath.maximum : NaNMath.minimum)(mat) # where to draw the contour plane + offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat) # where to draw the contour plane ) push!(handles, handle) needs_colorbar = true @@ -778,7 +778,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end clims = sp[:clims] - zmin, zmax = NaNMath.extrema(z) + zmin, zmax = ignoreNaN_extrema(z) extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax @@ -926,7 +926,7 @@ function py_compute_axis_minval(axis::Axis) for series in series_list(sp) v = series.d[axis[:letter]] if !isempty(v) - minval = NaNMath.min(minval, NaNMath.minimum(abs(v))) + minval = NaNMath.min(minval, ignoreNaN_minimum(abs(v))) end end end diff --git a/src/components.jl b/src/components.jl index 4a11bd7e..6a935c95 100644 --- a/src/components.jl +++ b/src/components.jl @@ -501,7 +501,7 @@ immutable ZValues zrange::Tuple{Float64,Float64} end -function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (NaNMath.minimum(values), NaNMath.maximum(values))) +function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (ignoreNaN_minimum(values), ignoreNaN_maximum(values))) ZValues(collect(float(values)), map(Float64, zrange)) end @@ -659,7 +659,7 @@ function directed_curve(args...; kw...) end function extrema_plus_buffer(v, buffmult = 0.2) - vmin,vmax = NaNMath.extrema(v) + vmin,vmax = ignoreNaN_extrema(v) vdiff = vmax-vmin buffer = vdiff * buffmult vmin - buffer, vmax + buffer diff --git a/src/layouts.jl b/src/layouts.jl index 003c63c1..8312d97b 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -704,7 +704,7 @@ function link_axes!(axes::Axis...) a1 = axes[1] for i=2:length(axes) a2 = axes[i] - expand_extrema!(a1, NaNMath.extrema(a2)) + expand_extrema!(a1, ignoreNaN_extrema(a2)) for k in (:extrema, :discrete_values, :continuous_values, :discrete_map) a2[k] = a1[k] end diff --git a/src/pipeline.jl b/src/pipeline.jl index 3a68e4a4..0c111e72 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -153,7 +153,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::KW) if get(kw, :smooth, false) x, y = kw[:x], kw[:y] β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) - sx = [NaNMath.minimum(x), NaNMath.maximum(x)] + sx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)] sy = β * sx + α push!(kw_list, merge(copy(kw), KW( :seriestype => :path, diff --git a/src/recipes.jl b/src/recipes.jl index 68ffd407..9f647f73 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -225,7 +225,7 @@ end fr = if yaxis[:scale] == :identity 0.0 else - NaNMath.min(axis_limits(yaxis)[1], NaNMath.minimum(y)) + NaNMath.min(axis_limits(yaxis)[1], ignoreNaN_minimum(y)) end end newx, newy = zeros(3n), zeros(3n) @@ -338,7 +338,7 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5NaNMath.mean(diff(procx)) + 0.5ignoreNaN_mean(diff(procx)) else Float64[0.5cycle(bw,i) for i=1:length(procx)] end @@ -366,7 +366,7 @@ end end # widen limits out a bit - expand_extrema!(axis, widen(NaNMath.extrema(xseg.pts)...)) + expand_extrema!(axis, widen(ignoreNaN_extrema(xseg.pts)...)) # switch back if !isvertical(d) @@ -414,8 +414,8 @@ end function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) w_adj = _scale_adjusted_values(T, w, wscale) - w_min = NaNMath.minimum(w_adj) - w_max = NaNMath.maximum(w_adj) + w_min = ignoreNaN_minimum(w_adj) + w_max = ignoreNaN_maximum(w_adj) baseline = _binbarlike_baseline(w_min, wscale) w_adj, baseline end @@ -550,7 +550,7 @@ Plots.@deps stepbins path function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) _cl(x) = ceil(Int, NaNMath.max(x, one(x))) _iqr(v) = quantile(v, 0.75) - quantile(v, 0.25) - _span(v) = NaNMath.maximum(v) - NaNMath.minimum(v) + _span(v) = ignoreNaN_maximum(v) - ignoreNaN_minimum(v) n_samples = length(linearindices(first(vs))) # Estimator for number of samples in one row/column of bins along each axis: @@ -919,7 +919,7 @@ end # get the joined vector function get_xy(v::AVec{OHLC}, x = 1:length(v)) - xdiff = 0.3NaNMath.mean(abs(diff(x))) + xdiff = 0.3ignoreNaN_mean(abs(diff(x))) x_out, y_out = zeros(0), zeros(0) for (i,ohlc) in enumerate(v) ox,oy = get_xy(ohlc, x[i], xdiff) @@ -984,8 +984,8 @@ end yflip := true aspect_ratio := 1 rs, cs, zs = findnz(z.surf) - xlim := NaNMath.extrema(cs) - ylim := NaNMath.extrema(rs) + xlim := ignoreNaN_extrema(cs) + ylim := ignoreNaN_extrema(rs) if d[:markershape] == :none markershape := :circle end @@ -1006,7 +1006,7 @@ end "Adds a+bx... straight line over the current plot" function abline!(plt::Plot, a, b; kw...) - plot!(plt, [NaNMath.extrema(plt)...], x -> b + a*x; kw...) + plot!(plt, [ignoreNaN_extrema(plt)...], x -> b + a*x; kw...) end abline!(args...; kw...) = abline!(current(), args...; kw...) diff --git a/src/utils.jl b/src/utils.jl index dddfdf19..bc133c7a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -3,7 +3,7 @@ calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for "Make histogram-like bins of data" function binData(data, nbins) - lo, hi = NaNMath.extrema(data) + lo, hi = ignoreNaN_extrema(data) edges = collect(linspace(lo, hi, nbins+1)) midpoints = calcMidpoints(edges) buckets = Int[max(2, min(searchsortedfirst(edges, x), length(edges)))-1 for x in data] @@ -109,7 +109,7 @@ function regressionXY(x, y) β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) # make a line segment - regx = [NaNMath.minimum(x), NaNMath.maximum(x)] + regx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)] regy = β * regx + α regx, regy end @@ -283,7 +283,7 @@ unzip{T}(xyuv::FixedSizeArrays.Vec{4,T}) = T[xyuv[1]], T[xyuv[2]], T[xyuv[ # given 2-element lims and a vector of data x, widen lims to account for the extrema of x function _expand_limits(lims, x) try - e1, e2 = NaNMath.extrema(x) + e1, e2 = ignoreNaN_extrema(x) lims[1] = NaNMath.min(lims[1], e1) lims[2] = NaNMath.max(lims[2], e2) # catch err @@ -334,17 +334,17 @@ sortedkeys(d::Dict) = sort(collect(keys(d))) "create an (n+1) list of the outsides of heatmap rectangles" function heatmap_edges(v::AVec) - vmin, vmax = NaNMath.extrema(v) + vmin, vmax = ignoreNaN_extrema(v) extra = 0.5 * (vmax-vmin) / (length(v)-1) vcat(vmin-extra, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra) end function calc_r_extrema(x, y) - xmin, xmax = NaNMath.extrema(x) - ymin, ymax = NaNMath.extrema(y) + xmin, xmax = ignoreNaN_extrema(x) + ymin, ymax = ignoreNaN_extrema(y) r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin) - NaNMath.extrema(r) + ignoreNaN_extrema(r) end function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) @@ -645,7 +645,7 @@ end # used in updating an existing series extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n) -extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + NaNMath.maximum(v)) +extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + ignoreNaN_maximum(v)) extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v) @@ -871,9 +871,9 @@ mm2px(mm::Real) = float(px / MM_PER_PX) "Smallest x in plot" -xmin(plt::Plot) = NaNMath.minimum([NaNMath.minimum(series.d[:x]) for series in plt.series_list]) +xmin(plt::Plot) = ignoreNaN_minimum([ignoreNaN_minimum(series.d[:x]) for series in plt.series_list]) "Largest x in plot" -xmax(plt::Plot) = NaNMath.maximum([NaNMath.maximum(series.d[:x]) for series in plt.series_list]) +xmax(plt::Plot) = ignoreNaN_maximum([ignoreNaN_maximum(series.d[:x]) for series in plt.series_list]) "Extrema of x-values in plot" -NaNMath.extrema(plt::Plot) = (xmin(plt), xmax(plt)) +ignoreNaN_extrema(plt::Plot) = (xmin(plt), xmax(plt)) diff --git a/test/runtests.jl b/test/runtests.jl index d7d4441c..dd0d4adf 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -78,12 +78,12 @@ facts("Axes") do @fact typeof(axis) --> Plots.Axis @fact Plots.discrete_value!(axis, "HI") --> (0.5, 1) @fact Plots.discrete_value!(axis, :yo) --> (1.5, 2) - @fact Plots.NaNMath.extrema(axis) --> (0.5,1.5) + @fact Plots.ignoreNaN_extrema(axis) --> (0.5,1.5) @fact axis[:discrete_map] --> Dict{Any,Any}(:yo => 2, "HI" => 1) Plots.discrete_value!(axis, ["x$i" for i=1:5]) Plots.discrete_value!(axis, ["x$i" for i=0:2]) - @fact Plots.NaNMath.extrema(axis) --> (0.5, 7.5) + @fact Plots.ignoreNaN_extrema(axis) --> (0.5, 7.5) end From 90f7e370f38849334764a004ad9feadc0a8f147a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 2 Jun 2017 14:58:49 +0200 Subject: [PATCH 149/720] make tests pass for gr and pyplot cf. #877 --- test/imgcomp.jl | 2 +- test/install_wkhtmltoimage.sh | 8 ++-- test/runtests.jl | 71 ++++++++++++++++++++++++++++------- test/travis_commands.jl | 15 +++++--- 4 files changed, 72 insertions(+), 24 deletions(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 890c374b..1934e6b6 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -13,7 +13,7 @@ try end -using Plots +# using Plots # reexported by StatPlots using StatPlots using FactCheck using Glob diff --git a/test/install_wkhtmltoimage.sh b/test/install_wkhtmltoimage.sh index b265d183..6fdf0d69 100755 --- a/test/install_wkhtmltoimage.sh +++ b/test/install_wkhtmltoimage.sh @@ -5,9 +5,11 @@ set -ex sudo apt-get -qq update # sudo apt-get install -y wkhtmltopdf -sudo apt-get install -y xfonts-75dpi -wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2/wkhtmltox-0.12.2_linux-trusty-amd64.deb -sudo dpkg -i wkhtmltox-0.12.2_linux-trusty-amd64.deb +sudo apt-get install -y xfonts-base +wget https://downloads.wkhtmltopdf.org/0.12/0.12.2/wkhtmltox-0.12.2_linux-precise-amd64.deb +sudo dpkg -i wkhtmltox-0.12.2_linux-precise-amd64.deb +# wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2/wkhtmltox-0.12.2_linux-trusty-amd64.deb +# sudo dpkg -i wkhtmltox-0.12.2_linux-trusty-amd64.deb wkhtmltoimage http://www.google.com test.png ls diff --git a/test/runtests.jl b/test/runtests.jl index dd0d4adf..1232915c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -19,31 +19,74 @@ img_eps = isinteractive() ? 1e-2 : 10e-2 # image_comparison_facts(:gadfly, skip=[4,6,23,24,27], eps=img_eps) # end -facts("PyPlot") do - @fact pyplot() --> Plots.PyPlotBackend() - @fact backend() --> Plots.PyPlotBackend() - - image_comparison_facts(:pyplot, skip=[6,25,30,31], eps=img_eps) -end facts("GR") do @fact gr() --> Plots.GRBackend() @fact backend() --> Plots.GRBackend() - if is_linux() && isinteractive() - image_comparison_facts(:gr, skip=[2,25,30,31], eps=img_eps) - end + image_comparison_facts(:gr, eps=img_eps) end -facts("Plotly") do - @fact plotly() --> Plots.PlotlyBackend() - @fact backend() --> Plots.PlotlyBackend() - # # until png generation is reliable on OSX, just test on linux - # @static is_linux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps) +facts("PyPlot") do + @fact pyplot() --> Plots.PyPlotBackend() + @fact backend() --> Plots.PyPlotBackend() + + image_comparison_facts(:pyplot, eps=img_eps) end +# The plotlyjs testimages return a connection error on travis: +# connect: connection refused (ECONNREFUSED) + +# facts("PlotlyJS") do +# @fact plotlyjs() --> Plots.PlotlyJSBackend() +# @fact backend() --> Plots.PlotlyJSBackend() +# +# if is_linux() && isinteractive() +# image_comparison_facts(:plotlyjs, +# skip=[ +# 2, # animation (skipped for speed) +# 27, # (polar plots) takes very long / not working +# 31, # animation (skipped for speed) +# ], +# eps=img_eps) +# end +# end + + +# InspectDR returns that error on travis: +# ERROR: LoadError: InitError: Cannot open display: +# in Gtk.GLib.GError(::Gtk.##229#230) at /home/travis/.julia/v0.5/Gtk/src/GLib/gerror.jl:17 + +# facts("InspectDR") do +# @fact inspectdr() --> Plots.InspectDRBackend() +# @fact backend() --> Plots.InspectDRBackend() +# +# image_comparison_facts(:inspectdr, +# skip=[ +# 2, # animation +# 6, # heatmap not defined +# 10, # heatmap not defined +# 22, # contour not defined +# 23, # pie not defined +# 27, # polar plot not working +# 28, # heatmap not defined +# 31, # animation +# ], +# eps=img_eps) +# end + + +# facts("Plotly") do +# @fact plotly() --> Plots.PlotlyBackend() +# @fact backend() --> Plots.PlotlyBackend() +# +# # # until png generation is reliable on OSX, just test on linux +# # @static is_linux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps) +# end + + # facts("Immerse") do # @fact immerse() --> Plots.ImmerseBackend() # @fact backend() --> Plots.ImmerseBackend() diff --git a/test/travis_commands.jl b/test/travis_commands.jl index d0ff84bd..f3abd0fb 100644 --- a/test/travis_commands.jl +++ b/test/travis_commands.jl @@ -1,8 +1,8 @@ -# Pkg.clone("ImageMagick") -# Pkg.build("ImageMagick") +Pkg.clone("ImageMagick") +Pkg.build("ImageMagick") -# Pkg.clone("GR") -# Pkg.build("GR") +Pkg.clone("GR") +Pkg.build("GR") Pkg.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git") @@ -11,11 +11,12 @@ Pkg.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git") Pkg.clone("StatPlots") Pkg.checkout("PlotUtils") -# Pkg.clone("https://github.com/JunoLab/Blink.jl.git") +# Pkg.clone("Blink") # Pkg.build("Blink") # import Blink # Blink.AtomShell.install() -# Pkg.clone("https://github.com/spencerlyon2/PlotlyJS.jl.git") +# Pkg.add("Rsvg") +# Pkg.add("PlotlyJS") # Pkg.checkout("RecipesBase") # Pkg.clone("VisualRegressionTests") @@ -25,4 +26,6 @@ ENV["PYTHON"] = "" Pkg.add("PyPlot") Pkg.build("PyPlot") +# Pkg.add("InspectDR") + Pkg.test("Plots"; coverage=false) From 6156228c8941726465b14b7bb9cf96499b3bf7ed Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 2 Jun 2017 15:07:17 +0200 Subject: [PATCH 150/720] install xfonts-75dpi for whtmltox --- test/install_wkhtmltoimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_wkhtmltoimage.sh b/test/install_wkhtmltoimage.sh index 6fdf0d69..061cf606 100755 --- a/test/install_wkhtmltoimage.sh +++ b/test/install_wkhtmltoimage.sh @@ -5,7 +5,7 @@ set -ex sudo apt-get -qq update # sudo apt-get install -y wkhtmltopdf -sudo apt-get install -y xfonts-base +sudo apt-get install -y xfonts-75dpi xfonts-base wget https://downloads.wkhtmltopdf.org/0.12/0.12.2/wkhtmltox-0.12.2_linux-precise-amd64.deb sudo dpkg -i wkhtmltox-0.12.2_linux-precise-amd64.deb # wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2/wkhtmltox-0.12.2_linux-trusty-amd64.deb From 3d3ec2a1940356fe10e521b26e91c63a31169536 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 2 Jun 2017 17:18:01 +0200 Subject: [PATCH 151/720] add info about default markersize in spy recipe --- src/recipes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/recipes.jl b/src/recipes.jl index 9f647f73..ec02911f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -990,6 +990,7 @@ end markershape := :circle end if d[:markersize] == default(:markersize) + info("In the spy recipe the default markersize is 1. If you are viewing a small matrix, you may consider increasing it with the markersize attribute.") markersize := 1 end markerstrokewidth := 0 From dc757cbf6cd0d1854fac73cff4335522e4522f0a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 2 Jun 2017 17:39:25 +0200 Subject: [PATCH 152/720] changed gr legend markers for fillrange --- src/backends/gr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index af02902b..ee12dcb4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1007,9 +1007,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) should_add_to_legend(series) || continue st = series[:seriestype] gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - if st == :path + if st == :path && series[:fillrange] == nothing GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) - elseif st == :shape + elseif st == :shape || series[:fillrange] != nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) l, r = xpos-0.07, xpos-0.01 b, t = ypos-0.4dy, ypos+0.4dy From ee5617c6b82d5ddab48f224f799cfea8a5ff74b2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 2 Jun 2017 18:55:47 +0200 Subject: [PATCH 153/720] added attribute for pyplot backend --- src/arg_desc.jl | 1 + src/args.jl | 2 ++ src/backends/pyplot.jl | 3 ++- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index cea77071..77bd3f25 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -80,6 +80,7 @@ const _arg_desc = KW( :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", +:legend_title => "String or nothing (default). Sets the legend title.", :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", diff --git a/src/args.jl b/src/args.jl index b93e2d98..adb51289 100644 --- a/src/args.jl +++ b/src/args.jl @@ -251,6 +251,7 @@ const _subplot_defaults = KW( :foreground_color_title => :match, # title color :color_palette => :auto, :legend => :best, + :legend_title => nothing, :colorbar => :legend, :clims => :auto, :legendfont => font(8), @@ -439,6 +440,7 @@ 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(:legend_title, :leg_title, :key_title) add_aliases(:colorbar, :cb, :cbar, :colorkey) add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits) add_aliases(:smooth, :regression, :reg) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 82237fbb..ebfd4d21 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -17,7 +17,7 @@ const _pyplot_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, + :grid, :legend, :legend_title, :colorbar, :marker_z, :line_z, :fill_z, :levels, :ribbon, :quiver, :arrow, @@ -1187,6 +1187,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # framealpha = 0.6 ) leg[:set_zorder](1000) + sp[:legend_title] != nothing && leg[:set_title](sp[:legend_title]) fgcolor = py_color(sp[:foreground_color_legend]) for txt in leg[:get_texts]() From ee23cb2185411b0e54262da5a7f996f6199a4624 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 3 Jun 2017 01:14:25 +0200 Subject: [PATCH 154/720] grid --> false in spy recipe, removed info, added example --- src/examples.jl | 10 ++++++++++ src/recipes.jl | 5 ++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 2fd6a0e9..60fa7fc5 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -318,6 +318,16 @@ PlotExample("Animation with subplots", end)] ), +PlotExample("Spy", + "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 5, markershape = :diamond)`", + [:(begin + a = spdiagm((ones(200), ones(199), ones(199), ones(150), ones(150)),(0, 1, -1, 50, -50)) + n = 20 + b = [i > j ? i * j : 0 for i in 1:n, j in 1:n] + plot(spy(a), spy(b, markersize = 5, markershape = :diamond), title = ["Unique nonzeros" "Different nonzeros"], yguide = "Row", xguide = "Column") + end)] +), + ] # --------------------------------------------------------------------------------- diff --git a/src/recipes.jl b/src/recipes.jl index ec02911f..26f4105a 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -976,6 +976,9 @@ end @assert length(g.args) == 1 && typeof(g.args[1]) <: AbstractMatrix seriestype := :spy mat = g.args[1] + if length(unique(mat)) <= 2 + legend --> nothing + end n,m = size(mat) Plots.SliceIt, 1:m, 1:n, Surface(mat) end @@ -990,7 +993,6 @@ end markershape := :circle end if d[:markersize] == default(:markersize) - info("In the spy recipe the default markersize is 1. If you are viewing a small matrix, you may consider increasing it with the markersize attribute.") markersize := 1 end markerstrokewidth := 0 @@ -1000,6 +1002,7 @@ end y := rs z := nothing seriestype := :scatter + grid --> false () end From 1a07c39fad7070351aae9f00fd09b2604b546d78 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 3 Jun 2017 13:27:38 +0200 Subject: [PATCH 155/720] changed spy plot example --- src/examples.jl | 9 ++++----- src/recipes.jl | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 60fa7fc5..05980152 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -319,12 +319,11 @@ PlotExample("Animation with subplots", ), PlotExample("Spy", - "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 5, markershape = :diamond)`", + "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`", [:(begin - a = spdiagm((ones(200), ones(199), ones(199), ones(150), ones(150)),(0, 1, -1, 50, -50)) - n = 20 - b = [i > j ? i * j : 0 for i in 1:n, j in 1:n] - plot(spy(a), spy(b, markersize = 5, markershape = :diamond), title = ["Unique nonzeros" "Different nonzeros"], yguide = "Row", xguide = "Column") + a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) + b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) + plot(spy(a, markershape = :star), spy(b), markersize = 3, title = ["Unique nonzeros" "Different nonzeros"]) end)] ), diff --git a/src/recipes.jl b/src/recipes.jl index 26f4105a..e8ea3096 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -976,7 +976,7 @@ end @assert length(g.args) == 1 && typeof(g.args[1]) <: AbstractMatrix seriestype := :spy mat = g.args[1] - if length(unique(mat)) <= 2 + if length(unique(mat[mat .!= 0])) < 2 legend --> nothing end n,m = size(mat) From 5e7756810d8d3ad79f8b60bc601129a4f063533c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 3 Jun 2017 13:47:24 +0200 Subject: [PATCH 156/720] changed default attribute to legendtitle --- src/arg_desc.jl | 2 +- src/args.jl | 4 ++-- src/backends/pyplot.jl | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 77bd3f25..ab51c820 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -80,7 +80,7 @@ const _arg_desc = KW( :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", -:legend_title => "String or nothing (default). Sets the legend title.", +:legendtitle => "String or nothing (default). Sets the legend title.", :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", diff --git a/src/args.jl b/src/args.jl index adb51289..1d1f0a0c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -251,7 +251,7 @@ const _subplot_defaults = KW( :foreground_color_title => :match, # title color :color_palette => :auto, :legend => :best, - :legend_title => nothing, + :legendtitle => nothing, :colorbar => :legend, :clims => :auto, :legendfont => font(8), @@ -440,7 +440,7 @@ 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(:legend_title, :leg_title, :key_title) +add_aliases(:legendtitle, :legend_title, :labeltitle, :label_title, :leg_title, :key_title) add_aliases(:colorbar, :cb, :cbar, :colorkey) add_aliases(:clims, :clim, :cbarlims, :cbar_lims, :climits, :color_limits) add_aliases(:smooth, :regression, :reg) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ebfd4d21..9a530997 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -17,7 +17,7 @@ const _pyplot_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :legend_title, :colorbar, + :grid, :legend, :legendtitle, :colorbar, :marker_z, :line_z, :fill_z, :levels, :ribbon, :quiver, :arrow, @@ -1187,7 +1187,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # framealpha = 0.6 ) leg[:set_zorder](1000) - sp[:legend_title] != nothing && leg[:set_title](sp[:legend_title]) + sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) fgcolor = py_color(sp[:foreground_color_legend]) for txt in leg[:get_texts]() From 9d115fc02e1e612030d03d5f19ab2ac42420865c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 3 Jun 2017 13:49:06 +0200 Subject: [PATCH 157/720] added space in arg_desc --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index ab51c820..ef0dda7b 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -80,7 +80,7 @@ const _arg_desc = KW( :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", -:legendtitle => "String or nothing (default). Sets the legend title.", +:legendtitle => "String or nothing (default). Sets the legend title.", :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", From b140fddebd138f8ac96905f79c95c271dafd8c8c Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Sun, 4 Jun 2017 10:02:20 +0200 Subject: [PATCH 158/720] gr: added support for legend title --- src/backends/gr.jl | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ee12dcb4..5e9c89c1 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -20,7 +20,7 @@ const _gr_attr = merge_with_base_supported([ :title, :window_title, :guide, :lims, :ticks, :scale, :flip, :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, + :grid, :legend, :legendtitle, :colorbar, :marker_z, :levels, :ribbon, :quiver, :orientation, @@ -980,6 +980,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) w = 0 i = 0 n = 0 + if sp[:legendtitle] != nothing + tbx, tby = gr_inqtext(0, 0, string(sp[:legendtitle])) + w = tbx[3] - tbx[1] + n += 1 + end for series in series_list(sp) should_add_to_legend(series) || continue n += 1 @@ -1003,6 +1008,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setlinewidth(1) GR.drawrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n) i = 0 + if sp[:legendtitle] != nothing + GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) + gr_set_textcolor(sp[:foreground_color_legend]) + gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) + ypos -= dy + end for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] From bad7772b1577f76c41385649414b3d53d5b073e4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 6 Jun 2017 14:45:30 +0200 Subject: [PATCH 159/720] fix-example12-transpose --- src/examples.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 2fd6a0e9..c842d433 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -115,7 +115,8 @@ PlotExample("Line types", PlotExample("Line styles", "", [:(begin - styles = filter(s -> s in Plots.supported_styles(), [:solid, :dash, :dot, :dashdot, :dashdotdot])' + styles = filter(s -> s in Plots.supported_styles(), [:solid, :dash, :dot, :dashdot, :dashdotdot]) + styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors n = length(styles) y = cumsum(randn(20,n),1) plot(y, line = (5, styles), label = map(string,styles)) From 18d29a0c7c2fc2ce81a2298cf46fb63f24181c25 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 6 Jun 2017 22:51:34 +0200 Subject: [PATCH 160/720] changed markershape to :dtriangle in spy example --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 05980152..81fd9872 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -323,7 +323,7 @@ PlotExample("Spy", [:(begin a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) - plot(spy(a, markershape = :star), spy(b), markersize = 3, title = ["Unique nonzeros" "Different nonzeros"]) + plot(spy(a, markershape = :dtriangle), spy(b), markersize = 3, title = ["Unique nonzeros" "Different nonzeros"]) end)] ), From 132306fef167dc00d80959128f22d52b84f43847 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 08:02:18 +0200 Subject: [PATCH 161/720] amend bins description --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index ef0dda7b..26d00a71 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the number of bins, or the edges, of the histogram, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd)", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values.", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", From db1dd618ea246cc8034e17d3a8f9c50a7e619074 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 11:01:47 +0200 Subject: [PATCH 162/720] Add example with linspace --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 26d00a71..f244ff99 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values.", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `linspace(extrema(x)..., 25)`", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", From f8bc9ba4769eedeb7d2a246e0eff66f98afcda85 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 16:05:35 +0200 Subject: [PATCH 163/720] update version number in tests --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 1934e6b6..61a48911 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -24,7 +24,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.11.2" +const _current_plots_version = v"0.11.3" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From a22412d39d5f6d83cd8487201977ee161fb8e9f7 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 16:05:51 +0200 Subject: [PATCH 164/720] Update News.md with 0.11.3 --- NEWS.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/NEWS.md b/NEWS.md index 2598bd5f..e796292b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,18 @@ ## 0.11 (current master/dev) +#### 0.11.3 + +- add HDF5 backend +- GR replaces PyPlot as first-choice backend +- support for legend position in GR +- smaller markers in GR +- better viewport size in GR +- fix glvisualize support +- remove bug with three-argument method of `text` +- `legendtitle` attribute added +- add test for `spy` + #### 0.11.0 - julia 0.6 compatibility From b8d1d9d7f151b2747931d715f754818c38b98132 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 16:06:04 +0200 Subject: [PATCH 165/720] Turn off precompilation for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 9b613056..6c2d129d 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From c7a13a4641414171b6b768179b86ad78616255f4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 16:54:24 +0200 Subject: [PATCH 166/720] Use ImageMagick release --- test/travis_commands.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/travis_commands.jl b/test/travis_commands.jl index f3abd0fb..4befaaef 100644 --- a/test/travis_commands.jl +++ b/test/travis_commands.jl @@ -1,4 +1,4 @@ -Pkg.clone("ImageMagick") +Pkg.add("ImageMagick") Pkg.build("ImageMagick") Pkg.clone("GR") From 51fabab7b7112f1ba683757acee6165ac586c013 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 16:59:20 +0200 Subject: [PATCH 167/720] Up FixedSizeArrays requirement to 0.3 --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 2f70e7f9..7ad8cc00 100644 --- a/REQUIRE +++ b/REQUIRE @@ -4,7 +4,7 @@ RecipesBase PlotUtils 0.4.1 PlotThemes 0.1.3 Reexport -FixedSizeArrays +FixedSizeArrays 0.3 Measures Showoff StatsBase 0.14.0 From df729cd0f6dd115e1e509372ae691efbedb0784a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 17:08:06 +0200 Subject: [PATCH 168/720] hotfix-FixedPointNumbers in require --- REQUIRE | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 7ad8cc00..c5b623ea 100644 --- a/REQUIRE +++ b/REQUIRE @@ -4,7 +4,8 @@ RecipesBase PlotUtils 0.4.1 PlotThemes 0.1.3 Reexport -FixedSizeArrays 0.3 +FixedSizeArrays +FixedPointNumbers 0.3 Measures Showoff StatsBase 0.14.0 From c41839a8164d8f9e9de26f0376793182392056f6 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 6 Jun 2017 10:18:05 +0200 Subject: [PATCH 169/720] Add legendtitle to example 13 --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index e0b05797..7025999f 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -119,7 +119,7 @@ PlotExample("Line styles", styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors n = length(styles) y = cumsum(randn(20,n),1) - plot(y, line = (5, styles), label = map(string,styles)) + plot(y, line = (5, styles), label = map(string,styles), legendtitle = "linestyle") end)] ), From 58c2f35bcf2219fb453f3dfddb57a2c0ed14bcc7 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 6 Jun 2017 10:29:43 +0200 Subject: [PATCH 170/720] reinclude Plots --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 61a48911..c25c7850 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -13,7 +13,7 @@ try end -# using Plots # reexported by StatPlots +using Plots using StatPlots using FactCheck using Glob From 4106161aa8a0d604b9b0ab655b5d50544c12378a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 6 Jun 2017 11:19:17 +0200 Subject: [PATCH 171/720] add colon --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 7025999f..53c27ed3 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -119,7 +119,7 @@ PlotExample("Line styles", styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors n = length(styles) y = cumsum(randn(20,n),1) - plot(y, line = (5, styles), label = map(string,styles), legendtitle = "linestyle") + plot(y, line = (5, styles), label = map(string,styles), legendtitle = "Linestyle:") end)] ), From a12f601b9c4d4bbd9721928053815cada50c9d06 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 6 Jun 2017 13:55:35 +0200 Subject: [PATCH 172/720] add legendtitle to example --- src/examples.jl | 2 +- test/runtests.jl | 37 ++++++++++++++++++------------------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 53c27ed3..7025999f 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -119,7 +119,7 @@ PlotExample("Line styles", styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors n = length(styles) y = cumsum(randn(20,n),1) - plot(y, line = (5, styles), label = map(string,styles), legendtitle = "Linestyle:") + plot(y, line = (5, styles), label = map(string,styles), legendtitle = "linestyle") end)] ), diff --git a/test/runtests.jl b/test/runtests.jl index 1232915c..4e3ceb1f 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,19 +7,6 @@ srand(1234) default(show=false, reuse=true) img_eps = isinteractive() ? 1e-2 : 10e-2 -# facts("Gadfly") do -# @fact gadfly() --> Plots.GadflyBackend() -# @fact backend() --> Plots.GadflyBackend() -# -# @fact typeof(plot(1:10)) --> Plots.Plot{Plots.GadflyBackend} -# @fact plot(Int[1,2,3], rand(3)) --> not(nothing) -# @fact plot(sort(rand(10)), rand(Int, 10, 3)) --> not(nothing) -# @fact plot!(rand(10,3), rand(10,3)) --> not(nothing) -# -# image_comparison_facts(:gadfly, skip=[4,6,23,24,27], eps=img_eps) -# end - - facts("GR") do @fact gr() --> Plots.GRBackend() @fact backend() --> Plots.GRBackend() @@ -35,6 +22,13 @@ facts("PyPlot") do image_comparison_facts(:pyplot, eps=img_eps) end +facts("UnicodePlots") do + @fact unicodeplots() --> Plots.UnicodePlotsBackend() + @fact backend() --> Plots.UnicodePlotsBackend() + + # lets just make sure it runs without error + @fact isa(plot(rand(10)), Plots.Plot) --> true +end # The plotlyjs testimages return a connection error on travis: # connect: connection refused (ECONNREFUSED) @@ -105,13 +99,18 @@ end # end -facts("UnicodePlots") do - @fact unicodeplots() --> Plots.UnicodePlotsBackend() - @fact backend() --> Plots.UnicodePlotsBackend() +# facts("Gadfly") do +# @fact gadfly() --> Plots.GadflyBackend() +# @fact backend() --> Plots.GadflyBackend() +# +# @fact typeof(plot(1:10)) --> Plots.Plot{Plots.GadflyBackend} +# @fact plot(Int[1,2,3], rand(3)) --> not(nothing) +# @fact plot(sort(rand(10)), rand(Int, 10, 3)) --> not(nothing) +# @fact plot!(rand(10,3), rand(10,3)) --> not(nothing) +# +# image_comparison_facts(:gadfly, skip=[4,6,23,24,27], eps=img_eps) +# end - # lets just make sure it runs without error - @fact isa(plot(rand(10)), Plots.Plot) --> true -end From 8a7b7f5c9b5ca6b1cfafda7efbec9394e063d153 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 17:03:58 +0200 Subject: [PATCH 173/720] Up requirement to 0.6 --- .travis.yml | 2 +- NEWS.md | 4 +++- REQUIRE | 2 +- test/imgcomp.jl | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1253ee9a..bbeac50e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ os: - linux # - osx julia: - - 0.5 + - 0.6 matrix: allow_failures: - julia: nightly diff --git a/NEWS.md b/NEWS.md index e796292b..2637f9bb 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,7 +10,9 @@ --- -## 0.11 (current master/dev) +## 0.12 (current master/dev) + +- 0.6 only #### 0.11.3 diff --git a/REQUIRE b/REQUIRE index c5b623ea..2d184bf7 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.5 +julia 0.6 RecipesBase PlotUtils 0.4.1 diff --git a/test/imgcomp.jl b/test/imgcomp.jl index c25c7850..994670f9 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -24,7 +24,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.11.3" +const _current_plots_version = v"0.12.0" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 7415a362c4839526c291a1134c8acb4e4215cac4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 17:06:06 +0200 Subject: [PATCH 174/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 6c2d129d..9b613056 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From f097fb57b5fd1da3fce6d6a1cf5c256054a14486 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 18:13:09 +0200 Subject: [PATCH 175/720] Fix some deprecation warnings --- src/backends/gr.jl | 4 ++-- src/components.jl | 2 +- src/deprecated/colors.jl | 2 +- src/series.jl | 4 ++-- src/subplots.jl | 2 +- src/types.jl | 6 +++--- src/utils.jl | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0f2a959b..cd9c0158 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -706,7 +706,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) rotation = sp[:xaxis][:rotation]) for (cv, dv) in zip(xticks...) # use xor ($) to get the right y coords - xi, yi = GR.wctondc(cv, (flip $ mirror) ? ymax : ymin) + xi, yi = GR.wctondc(cv, xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3, string(dv)) end @@ -723,7 +723,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) rotation = sp[:yaxis][:rotation]) for (cv, dv) in zip(yticks...) # use xor ($) to get the right y coords - xi, yi = GR.wctondc((flip $ mirror) ? xmax : xmin, cv) + xi, yi = GR.wctondc(xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) end diff --git a/src/components.jl b/src/components.jl index 6a935c95..8a78c9f5 100644 --- a/src/components.jl +++ b/src/components.jl @@ -507,7 +507,7 @@ end # ----------------------------------------------------------------------- -abstract AbstractSurface +abstract type AbstractSurface end "represents a contour or surface mesh" immutable Surface{M<:AMat} <: AbstractSurface diff --git a/src/deprecated/colors.jl b/src/deprecated/colors.jl index ebc75222..f73d5db6 100644 --- a/src/deprecated/colors.jl +++ b/src/deprecated/colors.jl @@ -1,5 +1,5 @@ -abstract ColorScheme +abstract type ColorScheme end Base.getindex(scheme::ColorScheme, i::Integer) = getColor(scheme, i) diff --git a/src/series.jl b/src/series.jl index f1ee5739..ca520168 100644 --- a/src/series.jl +++ b/src/series.jl @@ -6,7 +6,7 @@ # This should cut down on boilerplate code and allow more focused dispatch on type # note: returns meta information... mainly for use with automatic labeling from DataFrames for now -typealias FuncOrFuncs{F} Union{F, Vector{F}, Matrix{F}} +const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) @@ -318,7 +318,7 @@ end @recipe function f{T<:Colorant}(mat::AMat{T}) n, m = size(mat) - + if is_seriestype_supported(:image) seriestype := :image SliceIt, 1:m, 1:n, Surface(mat) diff --git a/src/subplots.jl b/src/subplots.jl index 924cc6c0..ccd1478c 100644 --- a/src/subplots.jl +++ b/src/subplots.jl @@ -32,7 +32,7 @@ get_subplot(plt::Plot, k) = plt.spmap[k] get_subplot(series::Series) = series.d[:subplot] get_subplot_index(plt::Plot, idx::Integer) = Int(idx) -get_subplot_index(plt::Plot, sp::Subplot) = findfirst(_ -> _ === sp, plt.subplots) +get_subplot_index(plt::Plot, sp::Subplot) = findfirst(x -> x === sp, plt.subplots) series_list(sp::Subplot) = sp.series_list # filter(series -> series.d[:subplot] === sp, sp.plt.series_list) diff --git a/src/types.jl b/src/types.jl index 284b6534..06ddb065 100644 --- a/src/types.jl +++ b/src/types.jl @@ -8,9 +8,9 @@ const KW = Dict{Symbol,Any} immutable PlotsDisplay <: Display end -abstract AbstractBackend -abstract AbstractPlot{T<:AbstractBackend} -abstract AbstractLayout +abstract type AbstractBackend end +abstract type AbstractPlot{T<:AbstractBackend} end +abstract type AbstractLayout end # ----------------------------------------------------------- diff --git a/src/utils.jl b/src/utils.jl index bc133c7a..1de784e1 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -469,7 +469,7 @@ ok(tup::Tuple) = ok(tup...) # compute one side of a fill range from a ribbon function make_fillrange_side(y, rib) frs = zeros(length(y)) - for (i, (yi, ri)) in enumerate(zip(y, Base.cycle(rib))) + for (i, (yi, ri)) in enumerate(zip(y, Base.Iterators.cycle(rib))) frs[i] = yi + ri end frs From 3a2ee0fc724b78e6986d356044e4b69bcb2fae67 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 7 Jun 2017 23:47:13 +0200 Subject: [PATCH 176/720] Fix some deprecations --- REQUIRE | 2 +- src/Plots.jl | 11 ++++++++++- src/examples.jl | 4 ++-- src/plot.jl | 2 +- src/recipes.jl | 2 +- src/utils.jl | 4 ++-- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/REQUIRE b/REQUIRE index 2d184bf7..39402c3d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.6 +julia 0.6-pre RecipesBase PlotUtils 0.4.1 diff --git a/src/Plots.jl b/src/Plots.jl index 9b613056..2f9caeca 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots @@ -118,6 +118,15 @@ ignoreNaN_extrema(x) = Base.extrema(x) # --------------------------------------------------------- +# to cater for block matrices, Base.transpose is recursive. +# This makes it impossible to create row vectors of String and Symbol with the transpose operator. +# This solves this issue, internally in Plots at least. + +Base.transpose(x::Symbol) = x +Base.transpose(x::String) = x + +# --------------------------------------------------------- + import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox diff --git a/src/examples.jl b/src/examples.jl index 7025999f..e4c13ca6 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -41,7 +41,7 @@ PlotExample("Colors", [:(begin y = rand(100) plot(0:10:100,rand(11,4),lab="lines",w=3,palette=:grays,fill=0, α=0.6) - scatter!(y, zcolor=abs(y-.5), m=(:heat,0.8,stroke(1,:green)), ms=10*abs(y-0.5)+4, lab="grad") + scatter!(y, zcolor=abs.(y-.5), m=(:heat,0.8,stroke(1,:green)), ms=10*abs.(y-0.5)+4, lab="grad") end)] ), @@ -269,7 +269,7 @@ PlotExample("Polar Plots", "", [:(begin Θ = linspace(0,1.5π,100) - r = abs(0.1randn(100)+sin(3Θ)) + r = abs.(0.1randn(100)+sin.(3Θ)) plot(Θ, r, proj=:polar, m=2) end)] ), diff --git a/src/plot.jl b/src/plot.jl index 2e8063af..3ab41701 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -60,7 +60,7 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...) # build our plot vector from the args n = length(plts_tail) + 1 - plts = Array(Plot, n) + plts = Array{Plot}(n) plts[1] = plt1 for (i,plt) in enumerate(plts_tail) plts[i+1] = plt diff --git a/src/recipes.jl b/src/recipes.jl index e8ea3096..a474bd74 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -669,7 +669,7 @@ end edge_x, edge_y, weights = x, y, z.surf float_weights = float(weights) - if is(float_weights, weights) + if float_weights === weights float_weights = deepcopy(float_weights) end for (i, c) in enumerate(float_weights) diff --git a/src/utils.jl b/src/utils.jl index 1de784e1..8f51fc4d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -355,8 +355,8 @@ function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) x = zeros(n) y = zeros(n) for i in 1:n - x[i] = cycle(r,i) * cos(cycle(phi,i)) - y[i] = cycle(r,i) * sin(cycle(phi,i)) + x[i] = cycle(r,i) * cos.(cycle(phi,i)) + y[i] = cycle(r,i) * sin.(cycle(phi,i)) end x, y end From 4dd176a7f29d596c04b0c070eb7e68f409fe4757 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 8 Jun 2017 00:19:36 +0200 Subject: [PATCH 177/720] add @eval in image_comparision_tests and replaced transpose in testexample 13 --- src/examples.jl | 3 ++- test/imgcomp.jl | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index e4c13ca6..85c41ca3 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -126,7 +126,8 @@ PlotExample("Line styles", PlotExample("Marker types", "", [:(begin - markers = filter(m -> m in Plots.supported_markers(), Plots._shape_keys)' + markers = filter(m -> m in Plots.supported_markers(), Plots._shape_keys) + markers = reshape(markers, 1, length(markers)) n = length(markers) x = linspace(0,10,n+2)[2:end-1] y = repmat(reverse(x)', n, 1) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 994670f9..cd3b7058 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -13,7 +13,7 @@ try end -using Plots +using Plots using StatPlots using FactCheck using Glob @@ -99,7 +99,7 @@ function image_comparison_facts(pkg::Symbol; for i in 1:length(Plots._examples) i in skip && continue if only == nothing || i in only - @fact image_comparison_tests(pkg, i, debug=debug, sigma=sigma, eps=eps) |> success --> true + @fact @eval(image_comparison_tests(Symbol(String(Symbol($pkg))[7:end]), $i, debug=$debug, sigma=$sigma, eps=$eps)) |> success --> true end end end From c0a8adc1678c6532a0973e8376f56faa9ec48bd9 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 8 Jun 2017 00:55:23 +0200 Subject: [PATCH 178/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 2f9caeca..29ae301c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 46cdbacf0b653184017f939f65e7bc7f6601bc92 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 7 Jun 2017 18:15:43 -0700 Subject: [PATCH 179/720] gr: removed println statement --- src/backends/gr.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index cd9c0158..dd82a03e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -448,7 +448,6 @@ gr_view_ycenter() = 0.5 * (viewport_plotarea[3] + viewport_plotarea[4]) function gr_legend_pos(s::Symbol,w,h) str = string(s) - println(str) if str == "best" str = "topright" end From 85111529820611569ff756904ceb3e03a1a3767b Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 8 Jun 2017 10:47:08 +0200 Subject: [PATCH 180/720] update Base..* to 0.6 syntax --- src/layouts.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/layouts.jl b/src/layouts.jl index 8312d97b..5f02411f 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -9,8 +9,8 @@ to_pixels(m::AbsoluteLength) = m.value / 0.254 const _cbar_width = 5mm -Base.:.*(m::Measure, n::Number) = m * n -Base.:.*(n::Number, m::Measure) = m * n +Base.broadcast(::typeof(Base.:.*), m::Measure, n::Number) = m * n +Base.broadcast(::typeof(Base.:.*), m::Number, n::Measure) = m * n Base.:-(m::Measure, a::AbstractArray) = map(ai -> m - ai, a) Base.:-(a::AbstractArray, m::Measure) = map(ai -> ai - m, a) Base.zero(::Type{typeof(mm)}) = 0mm From 8f6b0c50d6b564a3e3de20869a5928de5d791279 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 8 Jun 2017 12:54:25 +0200 Subject: [PATCH 181/720] ignoreNaN => ignorenan --- src/Plots.jl | 16 ++++++++-------- src/axes.jl | 8 ++++---- src/backends/glvisualize.jl | 16 ++++++++-------- src/backends/gr.jl | 6 +++--- src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 8 ++++---- src/components.jl | 4 ++-- src/layouts.jl | 2 +- src/pipeline.jl | 2 +- src/recipes.jl | 20 ++++++++++---------- src/utils.jl | 22 +++++++++++----------- test/runtests.jl | 4 ++-- 12 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 29ae301c..05f3f6d0 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -107,14 +107,14 @@ export # --------------------------------------------------------- import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563 -ignoreNaN_minimum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.minimum(x) -ignoreNaN_minimum(x) = Base.minimum(x) -ignoreNaN_maximum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.maximum(x) -ignoreNaN_maximum(x) = Base.maximum(x) -ignoreNaN_mean{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.mean(x) -ignoreNaN_mean(x) = Base.mean(x) -ignoreNaN_extrema{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.extrema(x) -ignoreNaN_extrema(x) = Base.extrema(x) +ignorenan_minimum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.minimum(x) +ignorenan_minimum(x) = Base.minimum(x) +ignorenan_maximum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.maximum(x) +ignorenan_maximum(x) = Base.maximum(x) +ignorenan_mean{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.mean(x) +ignorenan_mean(x) = Base.mean(x) +ignorenan_extrema{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.extrema(x) +ignorenan_extrema(x) = Base.extrema(x) # --------------------------------------------------------- diff --git a/src/axes.jl b/src/axes.jl index f629d22c..e53d3ccb 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -118,7 +118,7 @@ Base.show(io::IO, axis::Axis) = dumpdict(axis.d, "Axis", true) # Base.getindex(axis::Axis, k::Symbol) = getindex(axis.d, k) Base.setindex!(axis::Axis, v, ks::Symbol...) = setindex!(axis.d, v, ks...) Base.haskey(axis::Axis, k::Symbol) = haskey(axis.d, k) -ignoreNaN_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) +ignorenan_extrema(axis::Axis) = (ex = axis[:extrema]; (ex.emin, ex.emax)) const _scale_funcs = Dict{Symbol,Function}( @@ -349,11 +349,11 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = ignoreNaN_mean(diff(data)) + bw = d[:bar_width] = ignorenan_mean(diff(data)) end axis = sp.attr[Symbol(dsym, :axis)] - expand_extrema!(axis, ignoreNaN_maximum(data) + 0.5maximum(bw)) - expand_extrema!(axis, ignoreNaN_minimum(data) - 0.5minimum(bw)) + expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw)) + expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw)) end end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 5e78c046..26fba2e8 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -304,7 +304,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(ignorenan_extrema(d[:y])) end end else @@ -315,7 +315,7 @@ function extract_any_color(d, kw_args) kw_args[:color_norm] = Vec2f0(clims) end elseif clims == :auto - kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(d[:y])) + kw_args[:color_norm] = Vec2f0(ignorenan_extrema(d[:y])) else error("Unsupported limits: $clims") end @@ -482,7 +482,7 @@ function hover(to_hover, to_display, window) end function extract_extrema(d, kw_args) - xmin, xmax = ignoreNaN_extrema(d[:x]); ymin, ymax = ignoreNaN_extrema(d[:y]) + xmin, xmax = ignorenan_extrema(d[:x]); ymin, ymax = ignorenan_extrema(d[:y]) kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(xmin, ymin, xmax-xmin, ymax-ymin) nothing end @@ -509,7 +509,7 @@ function extract_colornorm(d, kw_args) else d[:y] end - kw_args[:color_norm] = Vec2f0(ignoreNaN_extrema(z)) + kw_args[:color_norm] = Vec2f0(ignorenan_extrema(z)) kw_args[:intensity] = map(Float32, collect(z)) end end @@ -781,7 +781,7 @@ function gl_bar(d, kw_args) # compute half-width of bars bw = nothing hw = if bw == nothing - ignoreNaN_mean(diff(x)) + ignorenan_mean(diff(x)) else Float64[cycle(bw,i)*0.5 for i=1:length(x)] end @@ -864,7 +864,7 @@ function gl_boxplot(d, kw_args) end # change q1 and q5 to show outliers # using maximum and minimum values inside the limits - q1, q5 = ignoreNaN_extrema(inside) + q1, q5 = ignorenan_extrema(inside) end # Box if notch @@ -1318,7 +1318,7 @@ function gl_contour(x, y, z, kw_args) T = eltype(z) levels = Contour.contours(map(T, x), map(T, y), z, h) result = Point2f0[] - zmin, zmax = get(kw_args, :limits, Vec2f0(ignoreNaN_extrema(z))) + zmin, zmax = get(kw_args, :limits, Vec2f0(ignorenan_extrema(z))) cmap = get(kw_args, :color_map, get(kw_args, :color, RGBA{Float32}(0,0,0,1))) colors = RGBA{Float32}[] for c in levels.contours @@ -1339,7 +1339,7 @@ end function gl_heatmap(x,y,z, kw_args) - get!(kw_args, :color_norm, Vec2f0(ignoreNaN_extrema(z))) + get!(kw_args, :color_norm, Vec2f0(ignorenan_extrema(z))) get!(kw_args, :color_map, Plots.make_gradient(cgrad())) delete!(kw_args, :intensity) I = GLVisualize.Intensity{1, Float32} diff --git a/src/backends/gr.jl b/src/backends/gr.jl index dd82a03e..d29bf48e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -264,7 +264,7 @@ end normalize_zvals(zv::Void) = zv function normalize_zvals(zv::AVec) - vmin, vmax = ignoreNaN_extrema(zv) + vmin, vmax = ignorenan_extrema(zv) if vmin == vmax zeros(length(zv)) else @@ -666,7 +666,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif ispolar(sp) r = gr_set_viewport_polar() - rmin, rmax = GR.adjustrange(ignoreNaN_minimum(r), ignoreNaN_maximum(r)) + rmin, rmax = GR.adjustrange(ignorenan_minimum(r), ignorenan_maximum(r)) # rmin, rmax = axis_limits(sp[:yaxis]) gr_polaraxes(rmin, rmax) @@ -851,7 +851,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # create the colorbar of contour levels if sp[:colorbar] != :none gr_set_viewport_cmap(sp) - l = round(Int32, 1000 + (h - ignoreNaN_minimum(h)) / (ignoreNaN_maximum(h) - ignoreNaN_minimum(h)) * 255) + l = round(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 3b681618..b8adcb0f 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -546,7 +546,7 @@ function plotly_series(plt::Plot, series::Series) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) grad = as_gradient(series[:markercolor], series[:markeralpha]) - zmin, zmax = ignoreNaN_extrema(series[:marker_z]) + zmin, zmax = ignorenan_extrema(series[:marker_z]) zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) [rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]] end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 9a530997..3733dbd4 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -705,11 +705,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # contours on the axis planes if series[:contours] for (zdir,mat) in (("x",x), ("y",y), ("z",z)) - offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat) + offset = (zdir == "y" ? ignorenan_maximum : ignorenan_minimum)(mat) handle = ax[:contourf](x, y, z, levelargs...; zdir = zdir, cmap = py_fillcolormap(series), - offset = (zdir == "y" ? ignoreNaN_maximum : ignoreNaN_minimum)(mat) # where to draw the contour plane + offset = (zdir == "y" ? ignorenan_maximum : ignorenan_minimum)(mat) # where to draw the contour plane ) push!(handles, handle) needs_colorbar = true @@ -778,7 +778,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end clims = sp[:clims] - zmin, zmax = ignoreNaN_extrema(z) + zmin, zmax = ignorenan_extrema(z) extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax @@ -926,7 +926,7 @@ function py_compute_axis_minval(axis::Axis) for series in series_list(sp) v = series.d[axis[:letter]] if !isempty(v) - minval = NaNMath.min(minval, ignoreNaN_minimum(abs(v))) + minval = NaNMath.min(minval, ignorenan_minimum(abs(v))) end end end diff --git a/src/components.jl b/src/components.jl index 8a78c9f5..0b882f01 100644 --- a/src/components.jl +++ b/src/components.jl @@ -501,7 +501,7 @@ immutable ZValues zrange::Tuple{Float64,Float64} end -function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (ignoreNaN_minimum(values), ignoreNaN_maximum(values))) +function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (ignorenan_minimum(values), ignorenan_maximum(values))) ZValues(collect(float(values)), map(Float64, zrange)) end @@ -659,7 +659,7 @@ function directed_curve(args...; kw...) end function extrema_plus_buffer(v, buffmult = 0.2) - vmin,vmax = ignoreNaN_extrema(v) + vmin,vmax = ignorenan_extrema(v) vdiff = vmax-vmin buffer = vdiff * buffmult vmin - buffer, vmax + buffer diff --git a/src/layouts.jl b/src/layouts.jl index 5f02411f..71f8b7a1 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -704,7 +704,7 @@ function link_axes!(axes::Axis...) a1 = axes[1] for i=2:length(axes) a2 = axes[i] - expand_extrema!(a1, ignoreNaN_extrema(a2)) + expand_extrema!(a1, ignorenan_extrema(a2)) for k in (:extrema, :discrete_values, :continuous_values, :discrete_map) a2[k] = a1[k] end diff --git a/src/pipeline.jl b/src/pipeline.jl index 0c111e72..39e9899d 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -153,7 +153,7 @@ function _add_smooth_kw(kw_list::Vector{KW}, kw::KW) if get(kw, :smooth, false) x, y = kw[:x], kw[:y] β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) - sx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)] + sx = [ignorenan_minimum(x), ignorenan_maximum(x)] sy = β * sx + α push!(kw_list, merge(copy(kw), KW( :seriestype => :path, diff --git a/src/recipes.jl b/src/recipes.jl index a474bd74..2da6ca60 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -225,7 +225,7 @@ end fr = if yaxis[:scale] == :identity 0.0 else - NaNMath.min(axis_limits(yaxis)[1], ignoreNaN_minimum(y)) + NaNMath.min(axis_limits(yaxis)[1], ignorenan_minimum(y)) end end newx, newy = zeros(3n), zeros(3n) @@ -338,7 +338,7 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5ignoreNaN_mean(diff(procx)) + 0.5ignorenan_mean(diff(procx)) else Float64[0.5cycle(bw,i) for i=1:length(procx)] end @@ -366,7 +366,7 @@ end end # widen limits out a bit - expand_extrema!(axis, widen(ignoreNaN_extrema(xseg.pts)...)) + expand_extrema!(axis, widen(ignorenan_extrema(xseg.pts)...)) # switch back if !isvertical(d) @@ -414,8 +414,8 @@ end function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) w_adj = _scale_adjusted_values(T, w, wscale) - w_min = ignoreNaN_minimum(w_adj) - w_max = ignoreNaN_maximum(w_adj) + w_min = ignorenan_minimum(w_adj) + w_max = ignorenan_maximum(w_adj) baseline = _binbarlike_baseline(w_min, wscale) w_adj, baseline end @@ -550,7 +550,7 @@ Plots.@deps stepbins path function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) _cl(x) = ceil(Int, NaNMath.max(x, one(x))) _iqr(v) = quantile(v, 0.75) - quantile(v, 0.25) - _span(v) = ignoreNaN_maximum(v) - ignoreNaN_minimum(v) + _span(v) = ignorenan_maximum(v) - ignorenan_minimum(v) n_samples = length(linearindices(first(vs))) # Estimator for number of samples in one row/column of bins along each axis: @@ -919,7 +919,7 @@ end # get the joined vector function get_xy(v::AVec{OHLC}, x = 1:length(v)) - xdiff = 0.3ignoreNaN_mean(abs(diff(x))) + xdiff = 0.3ignorenan_mean(abs(diff(x))) x_out, y_out = zeros(0), zeros(0) for (i,ohlc) in enumerate(v) ox,oy = get_xy(ohlc, x[i], xdiff) @@ -987,8 +987,8 @@ end yflip := true aspect_ratio := 1 rs, cs, zs = findnz(z.surf) - xlim := ignoreNaN_extrema(cs) - ylim := ignoreNaN_extrema(rs) + xlim := ignorenan_extrema(cs) + ylim := ignorenan_extrema(rs) if d[:markershape] == :none markershape := :circle end @@ -1010,7 +1010,7 @@ end "Adds a+bx... straight line over the current plot" function abline!(plt::Plot, a, b; kw...) - plot!(plt, [ignoreNaN_extrema(plt)...], x -> b + a*x; kw...) + plot!(plt, [ignorenan_extrema(plt)...], x -> b + a*x; kw...) end abline!(args...; kw...) = abline!(current(), args...; kw...) diff --git a/src/utils.jl b/src/utils.jl index 8f51fc4d..6f59d292 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -3,7 +3,7 @@ calcMidpoints(edges::AbstractVector) = Float64[0.5 * (edges[i] + edges[i+1]) for "Make histogram-like bins of data" function binData(data, nbins) - lo, hi = ignoreNaN_extrema(data) + lo, hi = ignorenan_extrema(data) edges = collect(linspace(lo, hi, nbins+1)) midpoints = calcMidpoints(edges) buckets = Int[max(2, min(searchsortedfirst(edges, x), length(edges)))-1 for x in data] @@ -109,7 +109,7 @@ function regressionXY(x, y) β, α = convert(Matrix{Float64}, [x ones(length(x))]) \ convert(Vector{Float64}, y) # make a line segment - regx = [ignoreNaN_minimum(x), ignoreNaN_maximum(x)] + regx = [ignorenan_minimum(x), ignorenan_maximum(x)] regy = β * regx + α regx, regy end @@ -283,7 +283,7 @@ unzip{T}(xyuv::FixedSizeArrays.Vec{4,T}) = T[xyuv[1]], T[xyuv[2]], T[xyuv[ # given 2-element lims and a vector of data x, widen lims to account for the extrema of x function _expand_limits(lims, x) try - e1, e2 = ignoreNaN_extrema(x) + e1, e2 = ignorenan_extrema(x) lims[1] = NaNMath.min(lims[1], e1) lims[2] = NaNMath.max(lims[2], e2) # catch err @@ -334,17 +334,17 @@ sortedkeys(d::Dict) = sort(collect(keys(d))) "create an (n+1) list of the outsides of heatmap rectangles" function heatmap_edges(v::AVec) - vmin, vmax = ignoreNaN_extrema(v) + vmin, vmax = ignorenan_extrema(v) extra = 0.5 * (vmax-vmin) / (length(v)-1) vcat(vmin-extra, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra) end function calc_r_extrema(x, y) - xmin, xmax = ignoreNaN_extrema(x) - ymin, ymax = ignoreNaN_extrema(y) + xmin, xmax = ignorenan_extrema(x) + ymin, ymax = ignorenan_extrema(y) r = 0.5 * NaNMath.min(xmax - xmin, ymax - ymin) - ignoreNaN_extrema(r) + ignorenan_extrema(r) end function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) @@ -645,7 +645,7 @@ end # used in updating an existing series extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n) -extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + ignoreNaN_maximum(v)) +extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + ignorenan_maximum(v)) extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z) extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v) @@ -871,9 +871,9 @@ mm2px(mm::Real) = float(px / MM_PER_PX) "Smallest x in plot" -xmin(plt::Plot) = ignoreNaN_minimum([ignoreNaN_minimum(series.d[:x]) for series in plt.series_list]) +xmin(plt::Plot) = ignorenan_minimum([ignorenan_minimum(series.d[:x]) for series in plt.series_list]) "Largest x in plot" -xmax(plt::Plot) = ignoreNaN_maximum([ignoreNaN_maximum(series.d[:x]) for series in plt.series_list]) +xmax(plt::Plot) = ignorenan_maximum([ignorenan_maximum(series.d[:x]) for series in plt.series_list]) "Extrema of x-values in plot" -ignoreNaN_extrema(plt::Plot) = (xmin(plt), xmax(plt)) +ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt)) diff --git a/test/runtests.jl b/test/runtests.jl index 4e3ceb1f..75f4302c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -120,12 +120,12 @@ facts("Axes") do @fact typeof(axis) --> Plots.Axis @fact Plots.discrete_value!(axis, "HI") --> (0.5, 1) @fact Plots.discrete_value!(axis, :yo) --> (1.5, 2) - @fact Plots.ignoreNaN_extrema(axis) --> (0.5,1.5) + @fact Plots.ignorenan_extrema(axis) --> (0.5,1.5) @fact axis[:discrete_map] --> Dict{Any,Any}(:yo => 2, "HI" => 1) Plots.discrete_value!(axis, ["x$i" for i=1:5]) Plots.discrete_value!(axis, ["x$i" for i=0:2]) - @fact Plots.ignoreNaN_extrema(axis) --> (0.5, 7.5) + @fact Plots.ignorenan_extrema(axis) --> (0.5, 7.5) end From 66d9c79befac537a62615651150d9a8a27877ae2 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 9 Jun 2017 15:58:09 +0200 Subject: [PATCH 182/720] turn off precompilation for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 05f3f6d0..96de10d0 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 40734bf90ec769c3c9e38db5f8d9d9122fb35797 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 9 Jun 2017 15:58:09 +0200 Subject: [PATCH 183/720] Revert "turn off precompilation for release" This reverts commit 66d9c79befac537a62615651150d9a8a27877ae2. --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 96de10d0..05f3f6d0 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 554d7ab88774583ce50cca677e6ee0fb94ce3541 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 1 May 2017 16:56:29 -0700 Subject: [PATCH 184/720] remove `@shorthands` --- src/Plots.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 05f3f6d0..35765a66 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -30,9 +30,6 @@ export with, twinx, - @userplot, - @shorthands, - pie, pie!, plot3d, @@ -156,16 +153,6 @@ include("backends.jl") # --------------------------------------------------------- -# define and export shorthand plotting method definitions -macro shorthands(funcname::Symbol) - funcname2 = Symbol(funcname, "!") - esc(quote - export $funcname, $funcname2 - $funcname(args...; kw...) = plot(args...; kw..., seriestype = $(quot(funcname))) - $funcname2(args...; kw...) = plot!(args...; kw..., seriestype = $(quot(funcname))) - end) -end - @shorthands scatter @shorthands bar @shorthands barh From 67e5598d28650064657c07edf0775e1aca14a2da Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Fri, 28 Apr 2017 22:43:23 -0700 Subject: [PATCH 185/720] Move the @userplot recipes https://github.com/JuliaPlots/RecipesBase.jl/pull/16 --- src/recipes.jl | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 2da6ca60..02221cac 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -1,53 +1,4 @@ - - -""" -You can easily define your own plotting recipes with convenience methods: - -``` -@userplot type GroupHist - args -end - -@recipe function f(gh::GroupHist) - # set some attributes, add some series, using gh.args as input -end - -# now you can plot like: -grouphist(rand(1000,4)) -``` -""" -macro userplot(expr) - _userplot(expr) -end - -function _userplot(expr::Expr) - if expr.head != :type - errror("Must call userplot on a type/immutable expression. Got: $expr") - end - - typename = expr.args[2] - funcname = Symbol(lowercase(string(typename))) - funcname2 = Symbol(funcname, "!") - - # return a code block with the type definition and convenience plotting methods - esc(quote - $expr - export $funcname, $funcname2 - $funcname(args...; kw...) = plot($typename(args); kw...) - $funcname2(args...; kw...) = plot!($typename(args); kw...) - end) -end - -function _userplot(sym::Symbol) - _userplot(:(type $sym - args - end)) -end - - -# ---------------------------------------------------------------------------------- - const _series_recipe_deps = Dict() function series_recipe_dependencies(st::Symbol, deps::Symbol...) From 4770f8b58088fe7df6bbe03ca1f9df20dec691c2 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 1 May 2017 05:27:53 -0700 Subject: [PATCH 186/720] Merge remote-tracking branch 'ChrisRackauckas/master' into patch-1 --- src/Plots.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plots.jl b/src/Plots.jl index 35765a66..da1c4513 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -5,6 +5,7 @@ module Plots using Reexport using FixedSizeArrays @reexport using RecipesBase +import RecipesBase: plot using Base.Meta @reexport using PlotUtils @reexport using PlotThemes From ac505ede4419080cedfcbff20ed19470f498ea15 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 1 May 2017 06:27:37 -0700 Subject: [PATCH 187/720] move abstract types and make PlotRecipe on abstract type --- src/recipes.jl | 2 +- src/types.jl | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 02221cac..2a44b6df 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -47,7 +47,7 @@ end num_series(x::AMat) = size(x,2) num_series(x) = 1 -RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::Plot) = throw(MethodError("Unmatched plot recipe: $T")) +RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::AbstractPlot) = throw(MethodError("Unmatched plot recipe: $T")) # --------------------------------------------------------------------------- diff --git a/src/types.jl b/src/types.jl index 06ddb065..3e07587b 100644 --- a/src/types.jl +++ b/src/types.jl @@ -8,10 +8,6 @@ const KW = Dict{Symbol,Any} immutable PlotsDisplay <: Display end -abstract type AbstractBackend end -abstract type AbstractPlot{T<:AbstractBackend} end -abstract type AbstractLayout end - # ----------------------------------------------------------- immutable InputWrapper{T} From 0a8d3f92513fabdda9ff33fd0a78501f9f95a833 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Sun, 14 May 2017 13:26:50 -0700 Subject: [PATCH 188/720] animate from RecipesBase --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index da1c4513..8f419e40 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -5,7 +5,7 @@ module Plots using Reexport using FixedSizeArrays @reexport using RecipesBase -import RecipesBase: plot +import RecipesBase: plot, animate using Base.Meta @reexport using PlotUtils @reexport using PlotThemes From 44b6157f174db2223b3afcc6db87060d21827d03 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 8 May 2017 08:40:34 -0700 Subject: [PATCH 189/720] cycle => _cycle --- src/backends/glvisualize.jl | 14 +++++----- src/backends/gr.jl | 28 +++++++++---------- src/backends/inspectdr.jl | 8 +++--- src/backends/plotly.jl | 6 ++--- src/backends/pyplot.jl | 22 +++++++-------- src/components.jl | 8 +++--- src/deprecated/backends/gadfly_shapes.jl | 2 +- src/pipeline.jl | 2 +- src/recipes.jl | 34 ++++++++++++------------ src/utils.jl | 28 +++++++++---------- 10 files changed, 76 insertions(+), 76 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 26fba2e8..ea42c598 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -783,7 +783,7 @@ function gl_bar(d, kw_args) hw = if bw == nothing ignorenan_mean(diff(x)) else - Float64[cycle(bw,i)*0.5 for i=1:length(x)] + Float64[_cycle(bw,i)*0.5 for i=1:length(x)] end # make fillto a vector... default fills to 0 @@ -797,7 +797,7 @@ function gl_bar(d, kw_args) sx, sy = m[1,1], m[2,2] for i=1:ny center = x[i] - hwi = abs(cycle(hw,i)); yi = y[i]; fi = cycle(fillto,i) + hwi = abs(_cycle(hw,i)); yi = y[i]; fi = _cycle(fillto,i) if Plots.isvertical(d) sz = (hwi*sx, yi*sy) else @@ -833,7 +833,7 @@ function gl_boxplot(d, kw_args) sx, sy = m[1,1], m[2,2] for (i,glabel) in enumerate(glabels) # filter y - values = y[filter(i -> cycle(x,i) == glabel, 1:length(y))] + values = y[filter(i -> _cycle(x,i) == glabel, 1:length(y))] # compute quantiles q1,q2,q3,q4,q5 = quantile(values, linspace(0,1,5)) # notch @@ -846,7 +846,7 @@ function gl_boxplot(d, kw_args) # make the shape center = Plots.discrete_value!(d[:subplot][:xaxis], glabel)[1] - hw = d[:bar_width] == nothing ? Plots._box_halfwidth*2 : cycle(d[:bar_width], i) + hw = d[:bar_width] == nothing ? Plots._box_halfwidth*2 : _cycle(d[:bar_width], i) l, m, r = center - hw/2, center, center + hw/2 # internal nodes for notches @@ -945,7 +945,7 @@ function scale_for_annotations!(series::Series, scaletype::Symbol = :pixels) msw, msh = anns.scalefactor offsets = Array(Vec2f0, length(anns.strs)) series[:markersize] = map(1:length(anns.strs)) do i - str = cycle(anns.strs, i) + str = _cycle(anns.strs, i) # get the width and height of the string (in mm) sw, sh = text_size(str, anns.font.pointsize) @@ -1058,7 +1058,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) kw = copy(kw_args) fr = d[:fillrange] ps = if all(x-> x >= 0, diff(d[:x])) # if is monotonic - vcat(points, Point2f0[(points[i][1], cycle(fr, i)) for i=length(points):-1:1]) + vcat(points, Point2f0[(points[i][1], _cycle(fr, i)) for i=length(points):-1:1]) else points end @@ -1231,7 +1231,7 @@ function gl_scatter(points, kw_args) if haskey(kw_args, :stroke_width) s = Reactive.value(kw_args[:scale]) sw = kw_args[:stroke_width] - if sw*5 > cycle(Reactive.value(s), 1)[1] # restrict marker stroke to 1/10th of scale (and handle arrays of scales) + if sw*5 > _cycle(Reactive.value(s), 1)[1] # restrict marker stroke to 1/10th of scale (and handle arrays of scales) kw_args[:stroke_width] = s[1] / 5f0 end end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d29bf48e..feb2e5eb 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -124,10 +124,10 @@ function gr_getcolorind(c) convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c))) end -gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(cycle(c,1))) -gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(cycle(c,1))) -gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(cycle(c,1))) -gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(cycle(c,1))) +gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(_cycle(c,1))) +gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1))) +gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1))) +gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1))) # -------------------------------------------------------------------------------------- @@ -301,23 +301,23 @@ function gr_draw_markers(series::Series, x, y, msize, mz) shapes = series[:markershape] if shapes != :none for i=1:length(x) - msi = cycle(msize, i) - shape = cycle(shapes, i) + msi = _cycle(msize, i) + shape = _cycle(shapes, i) cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor cfuncind = isa(shape, Shape) ? GR.setfillcolorind : GR.setmarkercolorind # draw a filled in shape, slightly bigger, to estimate a stroke if series[:markerstrokewidth] > 0 - cfunc(cycle(series[:markerstrokecolor], i)) #, series[:markerstrokealpha]) + cfunc(_cycle(series[:markerstrokecolor], i)) #, series[:markerstrokealpha]) gr_draw_marker(x[i], y[i], msi + series[:markerstrokewidth], shape) end # draw the shape if mz == nothing - cfunc(cycle(series[:markercolor], i)) #, series[:markeralpha]) + cfunc(_cycle(series[:markercolor], i)) #, series[:markeralpha]) else # pick a color from the pre-loaded gradient - ci = round(Int, 1000 + cycle(mz, i) * 255) + ci = round(Int, 1000 + _cycle(mz, i) * 255) cfuncind(ci) GR.settransparency(_gr_gradient_alpha[ci-999]) end @@ -808,9 +808,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng)) for (i,rng) in enumerate(iter_segments(series[:x], series[:y])) if length(rng) > 1 - gr_set_fillcolor(cycle(series[:fillcolor], i)) - fx = cycle(x, vcat(rng, reverse(rng))) - fy = vcat(cycle(fr_from,rng), cycle(fr_to,reverse(rng))) + gr_set_fillcolor(_cycle(series[:fillcolor], i)) + fx = _cycle(x, vcat(rng, reverse(rng))) + fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) # @show i rng fx fy GR.fillarea(fx, fy) end @@ -962,11 +962,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) x, y = series[:x][rng], series[:y][rng] # draw the interior - gr_set_fill(cycle(series[:fillcolor], i)) + gr_set_fill(_cycle(series[:fillcolor], i)) GR.fillarea(x, y) # draw the shapes - gr_set_line(series[:linewidth], :solid, cycle(series[:linecolor], i)) + gr_set_line(series[:linewidth], :solid, _cycle(series[:linecolor], i)) GR.polyline(x, y) end end diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 18b5b541..5e4250e1 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -265,8 +265,8 @@ For st in :shape: nmax = i if length(rng) > 1 linewidth = series[:linewidth] - linecolor = _inspectdr_mapcolor(cycle(series[:linecolor], i)) - fillcolor = _inspectdr_mapcolor(cycle(series[:fillcolor], i)) + linecolor = _inspectdr_mapcolor(_cycle(series[:linecolor], i)) + fillcolor = _inspectdr_mapcolor(_cycle(series[:fillcolor], i)) line = InspectDR.line( style=:solid, width=linewidth, color=linecolor ) @@ -280,8 +280,8 @@ For st in :shape: 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)) + 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 diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b8adcb0f..4f3c956c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -600,18 +600,18 @@ function plotly_series_shapes(plt::Plot, series::Series) :x => vcat(x[rng], x[rng[1]]), :y => vcat(y[rng], y[rng[1]]), :fill => "tozeroy", - :fillcolor => rgba_string(cycle(series[:fillcolor], i)), + :fillcolor => rgba_string(_cycle(series[:fillcolor], i)), )) if series[:markerstrokewidth] > 0 d_out[:line] = KW( - :color => rgba_string(cycle(series[:linecolor], i)), + :color => rgba_string(_cycle(series[:linecolor], i)), :width => series[:linewidth], :dash => string(series[:linestyle]), ) end d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false plotly_polar!(d_out, series) - plotly_hover!(d_out, cycle(series[:hover], i)) + plotly_hover!(d_out, _cycle(series[:hover], i)) push!(d_outs, d_out) end d_outs diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 3733dbd4..3372da4d 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -495,10 +495,10 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = if is3d(st) for rng in iter_segments(x, y, z) length(rng) < 2 && continue - push!(segments, [(cycle(x,i),cycle(y,i),cycle(z,i)) for i in rng]) + push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)) for i in rng]) end # for i=1:n - # segments[i] = [(cycle(x,i), cycle(y,i), cycle(z,i)), (cycle(x,i+1), cycle(y,i+1), cycle(z,i+1))] + # segments[i] = [(_cycle(x,i), _cycle(y,i), _cycle(z,i)), (_cycle(x,i+1), _cycle(y,i+1), _cycle(z,i+1))] # end lc = pyart3d.Line3DCollection(segments; kw...) lc[:set_array](lz) @@ -507,10 +507,10 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) else for rng in iter_segments(x, y) length(rng) < 2 && continue - push!(segments, [(cycle(x,i),cycle(y,i)) for i in rng]) + push!(segments, [(_cycle(x,i),_cycle(y,i)) for i in rng]) end # for i=1:n - # segments[i] = [(cycle(x,i), cycle(y,i)), (cycle(x,i+1), cycle(y,i+1))] + # segments[i] = [(_cycle(x,i), _cycle(y,i)), (_cycle(x,i+1), _cycle(y,i+1))] # end lc = pycollections.LineCollection(segments; kw...) lc[:set_array](lz) @@ -581,16 +581,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) lw = py_dpi_scale(plt, series[:markerstrokewidth]) for i=1:length(y) extrakw[:c] = if series[:marker_z] == nothing - py_color_fix(py_color(cycle(series[:markercolor],i)), x) + py_color_fix(py_color(_cycle(series[:markercolor],i)), x) else extrakw[:c] end - push!(handle, ax[:scatter](cycle(x,i), cycle(y,i); + push!(handle, ax[:scatter](_cycle(x,i), _cycle(y,i); label = series[:label], zorder = series[:series_plotindex] + 0.5, - marker = py_marker(cycle(shapes,i)), - s = py_dpi_scale(plt, cycle(series[:markersize],i) .^ 2), + marker = py_marker(_cycle(shapes,i)), + s = py_dpi_scale(plt, _cycle(series[:markersize],i) .^ 2), edgecolors = msc, linewidths = lw, extrakw... @@ -802,8 +802,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) path; label = series[:label], zorder = series[:series_plotindex], - edgecolor = py_color(cycle(series[:linecolor], i)), - facecolor = py_color(cycle(series[:fillcolor], i)), + edgecolor = py_color(_cycle(series[:linecolor], i)), + facecolor = py_color(_cycle(series[:fillcolor], i)), linewidth = py_dpi_scale(plt, series[:linewidth]), fill = true ) @@ -1166,7 +1166,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # add a line/marker and a label push!(handles, if series[:seriestype] == :shape PyPlot.plt[:Line2D]((0,1),(0,0), - color = py_color(cycle(series[:fillcolor],1)), + color = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, 4) ) else diff --git a/src/components.jl b/src/components.jl index 0b882f01..9db2f04b 100644 --- a/src/components.jl +++ b/src/components.jl @@ -446,7 +446,7 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels) msw,msh = anns.scalefactor msize = Float64[] shapes = Shape[begin - str = cycle(anns.strs,i) + str = _cycle(anns.strs,i) # get the width and height of the string (in mm) sw, sh = text_size(str, anns.font.pointsize) @@ -462,7 +462,7 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels) # and then re-scale a copy of baseshape to match the w/h ratio maxscale = max(xscale, yscale) push!(msize, maxscale) - baseshape = cycle(get(anns.baseshape),i) + baseshape = _cycle(get(anns.baseshape),i) shape = scale(baseshape, msw*xscale/maxscale, msh*yscale/maxscale, (0,0)) end for i=1:length(anns.strs)] series[:markershape] = shapes @@ -479,13 +479,13 @@ end Base.start(ea::EachAnn) = 1 Base.done(ea::EachAnn, i) = ea.anns == nothing || isempty(ea.anns.strs) || i > length(ea.y) function Base.next(ea::EachAnn, i) - tmp = cycle(ea.anns.strs,i) + tmp = _cycle(ea.anns.strs,i) str,fnt = if isa(tmp, PlotText) tmp.str, tmp.font else tmp, ea.anns.font end - ((cycle(ea.x,i), cycle(ea.y,i), str, fnt), i+1) + ((_cycle(ea.x,i), _cycle(ea.y,i), str, fnt), i+1) end annotations(::Void) = [] diff --git a/src/deprecated/backends/gadfly_shapes.jl b/src/deprecated/backends/gadfly_shapes.jl index 8ee1b9ef..9c70c90c 100644 --- a/src/deprecated/backends/gadfly_shapes.jl +++ b/src/deprecated/backends/gadfly_shapes.jl @@ -84,7 +84,7 @@ function make_polygon(geom::ShapeGeometry, xs::AbstractArray, ys::AbstractArray, x = Compose.x_measure(xs[mod1(i, length(xs))]) y = Compose.y_measure(ys[mod1(i, length(ys))]) r = rs[mod1(i, length(rs))] - polys[i] = T[(x + r * sx, y + r * sy) for (sx,sy) in cycle(geom.vertices, i)] + polys[i] = T[(x + r * sx, y + r * sy) for (sx,sy) in _cycle(geom.vertices, i)] end Gadfly.polygon(polys, geom.tag) end diff --git a/src/pipeline.jl b/src/pipeline.jl index 39e9899d..83eff845 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -262,7 +262,7 @@ function _subplot_setup(plt::Plot, d::KW, kw_list::Vector{KW}) for kw in kw_list # get the Subplot object to which the series belongs. sps = get(kw, :subplot, :auto) - sp = get_subplot(plt, cycle(sps == :auto ? plt.subplots : plt.subplots[sps], command_idx(kw_list,kw))) + sp = get_subplot(plt, _cycle(sps == :auto ? plt.subplots : plt.subplots[sps], command_idx(kw_list,kw))) kw[:subplot] = sp # extract subplot/axis attributes from kw and add to sp_attr diff --git a/src/recipes.jl b/src/recipes.jl index 2da6ca60..91b0d883 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -232,7 +232,7 @@ end for i=1:n rng = 3i-2:3i newx[rng] = [x[i], x[i], NaN] - newy[rng] = [cycle(fr,i), y[i], NaN] + newy[rng] = [_cycle(fr,i), y[i], NaN] end x := newx y := newy @@ -284,16 +284,16 @@ end for rng in iter_segments(args...) length(rng) < 2 && continue ts = linspace(0, 1, npoints) - nanappend!(newx, map(t -> bezier_value(cycle(x,rng), t), ts)) - nanappend!(newy, map(t -> bezier_value(cycle(y,rng), t), ts)) + nanappend!(newx, map(t -> bezier_value(_cycle(x,rng), t), ts)) + nanappend!(newy, map(t -> bezier_value(_cycle(y,rng), t), ts)) if z != nothing - nanappend!(newz, map(t -> bezier_value(cycle(z,rng), t), ts)) + nanappend!(newz, map(t -> bezier_value(_cycle(z,rng), t), ts)) end if fr != nothing - nanappend!(newfr, map(t -> bezier_value(cycle(fr,rng), t), ts)) + nanappend!(newfr, map(t -> bezier_value(_cycle(fr,rng), t), ts)) end # if lz != nothing - # lzrng = cycle(lz, rng) # the line_z's for this segment + # lzrng = _cycle(lz, rng) # the line_z's for this segment # push!(newlz, 0.0) # append!(newlz, map(t -> lzrng[1+floor(Int, t * (length(rng)-1))], ts)) # end @@ -358,8 +358,8 @@ end yi = procy[i] if !isnan(yi) center = procx[i] - hwi = cycle(hw,i) - fi = cycle(fillto,i) + hwi = _cycle(hw,i) + fi = _cycle(fillto,i) push!(xseg, center-hwi, center-hwi, center+hwi, center+hwi, center-hwi) push!(yseg, yi, fi, fi, yi, yi) end @@ -755,9 +755,9 @@ function error_coords(xorig, yorig, ebar) x, y = Array(float_extended_type(xorig), 0), Array(Float64, 0) # for each point, create a line segment from the bottom to the top of the errorbar for i = 1:max(length(xorig), length(yorig)) - xi = cycle(xorig, i) - yi = cycle(yorig, i) - ebi = cycle(ebar, i) + xi = _cycle(xorig, i) + yi = _cycle(yorig, i) + ebi = _cycle(ebar, i) nanappend!(x, [xi, xi]) e1, e2 = if istuple(ebi) first(ebi), last(ebi) @@ -810,11 +810,11 @@ function quiver_using_arrows(d::KW) x, y = zeros(0), zeros(0) for i = 1:max(length(xorig), length(yorig)) # get the starting position - xi = cycle(xorig, i) - yi = cycle(yorig, i) + xi = _cycle(xorig, i) + yi = _cycle(yorig, i) # get the velocity - vi = cycle(velocity, i) + vi = _cycle(velocity, i) vx, vy = if istuple(vi) first(vi), last(vi) elseif isscalar(vi) @@ -847,12 +847,12 @@ function quiver_using_hack(d::KW) for i = 1:max(length(xorig), length(yorig)) # get the starting position - xi = cycle(xorig, i) - yi = cycle(yorig, i) + xi = _cycle(xorig, i) + yi = _cycle(yorig, i) p = P2(xi, yi) # get the velocity - vi = cycle(velocity, i) + vi = _cycle(velocity, i) vx, vy = if istuple(vi) first(vi), last(vi) elseif isscalar(vi) diff --git a/src/utils.jl b/src/utils.jl index 6f59d292..f5c16e8e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -192,7 +192,7 @@ function iter_segments(args...) end # helpers to figure out if there are NaN values in a list of array types -anynan(i::Int, args::Tuple) = any(a -> !isfinite(cycle(a,i)), args) +anynan(i::Int, args::Tuple) = any(a -> !isfinite(_cycle(a,i)), args) anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend) @@ -243,19 +243,19 @@ notimpl() = error("This has not been implemented yet") isnothing(x::Void) = true isnothing(x) = false -cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj -cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj +_cycle(wrapper::InputWrapper, idx::Int) = wrapper.obj +_cycle(wrapper::InputWrapper, idx::AVec{Int}) = wrapper.obj -cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))] -cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))] -cycle(v, idx::Int) = v +_cycle(v::AVec, idx::Int) = v[mod1(idx, length(v))] +_cycle(v::AMat, idx::Int) = size(v,1) == 1 ? v[1, mod1(idx, size(v,2))] : v[:, mod1(idx, size(v,2))] +_cycle(v, idx::Int) = v -cycle(v::AVec, indices::AVec{Int}) = map(i -> cycle(v,i), indices) -cycle(v::AMat, indices::AVec{Int}) = map(i -> cycle(v,i), indices) -cycle(v, indices::AVec{Int}) = fill(v, length(indices)) +_cycle(v::AVec, indices::AVec{Int}) = map(i -> _cycle(v,i), indices) +_cycle(v::AMat, indices::AVec{Int}) = map(i -> _cycle(v,i), indices) +_cycle(v, indices::AVec{Int}) = fill(v, length(indices)) -cycle(grad::ColorGradient, idx::Int) = cycle(grad.colors, idx) -cycle(grad::ColorGradient, indices::AVec{Int}) = cycle(grad.colors, indices) +_cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx) +_cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices) makevec(v::AVec) = v makevec{T}(v::T) = T[v] @@ -292,7 +292,7 @@ function _expand_limits(lims, x) nothing end -expand_data(v, n::Integer) = [cycle(v, i) for i=1:n] +expand_data(v, n::Integer) = [_cycle(v, i) for i=1:n] # if the type exists in a list, replace the first occurence. otherwise add it to the end function addOrReplace(v::AbstractVector, t::DataType, args...; kw...) @@ -355,8 +355,8 @@ function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) x = zeros(n) y = zeros(n) for i in 1:n - x[i] = cycle(r,i) * cos.(cycle(phi,i)) - y[i] = cycle(r,i) * sin.(cycle(phi,i)) + x[i] = _cycle(r,i) * cos.(_cycle(phi,i)) + y[i] = _cycle(r,i) * sin.(_cycle(phi,i)) end x, y end From 49fc903334fb3a347cfa63c96e57699e75ba5aa8 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas Date: Mon, 8 May 2017 08:46:50 -0700 Subject: [PATCH 190/720] fix last cycle --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 91b0d883..67a4950d 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -340,7 +340,7 @@ end hw = if bw == nothing 0.5ignorenan_mean(diff(procx)) else - Float64[0.5cycle(bw,i) for i=1:length(procx)] + Float64[0.5_cycle(bw,i) for i=1:length(procx)] end # make fillto a vector... default fills to 0 From 1d98acc407738a617089adde3b4085fa12c9c321 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Fri, 9 Jun 2017 22:04:48 +0200 Subject: [PATCH 191/720] deactivate precompilation for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 8f419e40..ccbd6c9a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From e9ab8c4dac28025e806a4f46f9c61bfec79d831e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 9 Jun 2017 22:57:23 +0200 Subject: [PATCH 192/720] require RecipesBase 0.2.0 --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 39402c3d..44e1623d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,6 +1,6 @@ julia 0.6-pre -RecipesBase +RecipesBase 0.2.0 PlotUtils 0.4.1 PlotThemes 0.1.3 Reexport From 9a1afb237633aa4c660e569c7299f412b332ef0b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 10 Jun 2017 23:13:03 +0200 Subject: [PATCH 193/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index ccbd6c9a..8f419e40 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From a1df3250515c488ff1c5fd68eb3a368a5f52e014 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 11 Jun 2017 22:25:15 +0200 Subject: [PATCH 194/720] Remove all 0.5-compliant uses of the transpose operator (') A horrible change, but one required by the metadata maintainers. --- src/Plots.jl | 9 ++++++--- src/examples.jl | 6 +++--- src/recipes.jl | 8 ++++---- src/utils.jl | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 8f419e40..989ac6ae 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots @@ -120,8 +120,11 @@ ignorenan_extrema(x) = Base.extrema(x) # This makes it impossible to create row vectors of String and Symbol with the transpose operator. # This solves this issue, internally in Plots at least. -Base.transpose(x::Symbol) = x -Base.transpose(x::String) = x + +# commented out on the insistence of the METADATA maintainers + +#Base.transpose(x::Symbol) = x +#Base.transpose(x::String) = x # --------------------------------------------------------- diff --git a/src/examples.jl b/src/examples.jl index 85c41ca3..6702832c 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -130,7 +130,7 @@ PlotExample("Marker types", markers = reshape(markers, 1, length(markers)) n = length(markers) x = linspace(0,10,n+2)[2:end-1] - y = repmat(reverse(x)', n, 1) + y = repmat(reshape(reverse(x),1,:), n, 1) scatter(x, y, m=(8,:auto), lab=map(string,markers), bg=:linen, xlim=(0,10), ylim=(0,10)) end)] ), @@ -216,7 +216,7 @@ PlotExample("Contours", x = 1:0.5:20 y = 1:0.5:10 f(x,y) = (3x+y^2)*abs(sin(x)+cos(y)) - X = repmat(x', length(y), 1) + X = repmat(reshape(x,1,:), length(y), 1) Y = repmat(y, 1, length(x)) Z = map(f, X, Y) p1 = contour(x, y, f, fill=true) @@ -280,7 +280,7 @@ PlotExample("Heatmap, categorical axes, and aspect_ratio", [:(begin xs = [string("x",i) for i=1:10] ys = [string("y",i) for i=1:4] - z = float((1:4)*(1:10)') + z = float((1:4)*reshape(1:10,1,:)) heatmap(xs, ys, z, aspect_ratio=1) end)] ), diff --git a/src/recipes.jl b/src/recipes.jl index e896dcac..64dd2c00 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -870,7 +870,7 @@ end # get the joined vector function get_xy(v::AVec{OHLC}, x = 1:length(v)) - xdiff = 0.3ignorenan_mean(abs(diff(x))) + xdiff = 0.3ignorenan_mean(abs.(diff(x))) x_out, y_out = zeros(0), zeros(0) for (i,ohlc) in enumerate(v) ox,oy = get_xy(ohlc, x[i], xdiff) @@ -911,7 +911,7 @@ end # "Sparsity plot... heatmap of non-zero values of a matrix" # function spy{T<:Real}(z::AMat{T}; kw...) -# mat = map(zi->float(zi!=0), z)' +# mat = reshape(map(zi->float(zi!=0), z),1,:) # xn, yn = size(mat) # heatmap(mat; leg=false, yflip=true, aspect_ratio=:equal, # xlim=(0.5, xn+0.5), ylim=(0.5, yn+0.5), @@ -1005,7 +1005,7 @@ end end library = PlotUtils.color_libraries[cl.args[1]] - z = sqrt.((1:15)*(1:20)') + z = sqrt.((1:15)*reshape(1:20,1,:)) seriestype := :heatmap ticks := nothing @@ -1029,7 +1029,7 @@ end if !(length(grad.args) == 1 && isa(grad.args[1], Symbol)) error("showgradient takes the name of a color gradient as a Symbol") end - z = sqrt.((1:15)*(1:20)') + z = sqrt.((1:15)*reshape(1:20,1,:)) seriestype := :heatmap ticks := nothing legend := false diff --git a/src/utils.jl b/src/utils.jl index f5c16e8e..d49b1fc7 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -324,7 +324,7 @@ function replaceAliases!(d::KW, aliases::Dict{Symbol,Symbol}) end end -createSegments(z) = collect(repmat(z',2,1))[2:end] +createSegments(z) = collect(repmat(reshape(z,1,:),2,1))[2:end] Base.first(c::Colorant) = c Base.first(x::Symbol) = x From c808cbb4fa69e783878b40e4e63c4740a751c539 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 11 Jun 2017 22:28:07 +0200 Subject: [PATCH 195/720] restore precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 989ac6ae..a23d6a8d 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From d3b825b49f89f3822da06d3136cee48fba735ca2 Mon Sep 17 00:00:00 2001 From: florian oswald Date: Mon, 12 Jun 2017 12:29:19 +0200 Subject: [PATCH 196/720] fix docstrings. provide 2 methods `scalefontsizes` now, with and without an argument. no argument version resets to initial values, with argument you rescale the current sizes. --- src/components.jl | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/components.jl b/src/components.jl index efbe946e..6de1387a 100644 --- a/src/components.jl +++ b/src/components.jl @@ -297,13 +297,23 @@ function scalefontsize(k::Symbol, factor::Number) f.pointsize = round(Int, factor * f.pointsize) default(k, f) end + +""" + scalefontsizes(factor::Number) + +Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()` +""" function scalefontsizes(factor::Number) for k in (:titlefont, :guidefont, :tickfont, :legendfont) scalefontsize(k, factor) end end -"Resets font sizes to initial default values" +""" + scalefontsizes() + +Resets font sizes to initial default values. +""" function scalefontsizes() for k in (:titlefont, :guidefont, :tickfont, :legendfont) f = default(k) From b3efcf9b681cb5d999299dba827f829d208931f6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 12 Jun 2017 20:39:49 +0200 Subject: [PATCH 197/720] reduced colorbar size for z axis limits >= 1e7 --- src/backends/pyplot.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 3372da4d..72cf508c 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1220,7 +1220,8 @@ function _update_plot_object(plt::Plot{PyPlotBackend}) if haskey(sp.attr, :cbar_ax) cbw = sp.attr[:cbar_width] # this is the bounding box of just the colors of the colorbar (not labels) - cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox)+2mm, _cbar_width-1mm, height(sp.bbox)-4mm) + has_toplabel = sp[:zaxis][:extrema].emax >= 1e7 + cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 8mm : 4mm)) pcts = bbox_to_pcts(cb_bbox, figw, figh) sp.attr[:cbar_ax][:set_position](pcts) end From 5b6423ec6c80ad8260592330874dca00fc0a050e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 12 Jun 2017 22:15:57 +0200 Subject: [PATCH 198/720] only change top corners of colorbar axes --- 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 72cf508c..f7ca62ff 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1221,7 +1221,7 @@ function _update_plot_object(plt::Plot{PyPlotBackend}) cbw = sp.attr[:cbar_width] # this is the bounding box of just the colors of the colorbar (not labels) has_toplabel = sp[:zaxis][:extrema].emax >= 1e7 - cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 8mm : 4mm)) + cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 6mm : 4mm)) pcts = bbox_to_pcts(cb_bbox, figw, figh) sp.attr[:cbar_ax][:set_position](pcts) end From 57b9602b1327d3db0e716c49312ff8e1dc979c74 Mon Sep 17 00:00:00 2001 From: Seth Bromberger Date: Thu, 15 Jun 2017 20:12:26 -0700 Subject: [PATCH 199/720] Update output.jl Change `readall` to `readstring` for 0.6- compatibility. --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index 0482f325..814f8884 100644 --- a/src/output.jl +++ b/src/output.jl @@ -220,7 +220,7 @@ if is_installed("FileIO") FileIO.save(pngfn, s) # now write from the file - write(io, readall(open(pngfn))) + write(io, readstring(open(pngfn))) end end From 86149ba3a75540cfe96e63ba61a670f4274173cb Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Fri, 16 Jun 2017 17:17:01 -0400 Subject: [PATCH 200/720] Conform to changes in InspectDR.PlotLayout. --- src/backends/inspectdr.jl | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 5e4250e1..d7ef859c 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -362,30 +362,29 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) a.xlabel = xaxis[:guide]; a.ylabels = [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, + l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot]) + l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside]) + l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis]) + l[:font_title] = 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 = InspectDR.Font(xaxis[:guidefont].family, + l[:font_axislabel] = InspectDR.Font(xaxis[:guidefont].family, _inspectdr_mapptsize(xaxis[:guidefont].pointsize), color = _inspectdr_mapcolor(xaxis[:foreground_color_guide]) ) - l.fntticklabel = InspectDR.Font(xaxis[:tickfont].family, + l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfont].family, _inspectdr_mapptsize(xaxis[:tickfont].pointsize), color = _inspectdr_mapcolor(xaxis[:foreground_color_text]) ) - leg = l.legend - leg.enabled = (sp[:legend] != :none) - #leg.width = 150 #TODO: compute??? - leg.font = InspectDR.Font(sp[:legendfont].family, + l[:enable_legend] = (sp[:legend] != :none) + #l[:halloc_legend] = 150 #TODO: compute??? + l[:font_legend] = 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]) + l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend]) end # called just before updating layout bounding boxes... in case you need to prep @@ -399,7 +398,7 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) #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]) + mplot.layout[:frame].fillcolor = _inspectdr_mapcolor(plt[:background_color_outside]) resize!(mplot.subplots, length(plt.subplots)) nsubplots = length(plt.subplots) @@ -421,15 +420,15 @@ function _before_layout_calcs(plt::Plot{InspectDRBackend}) #Do not yet support absolute plot positionning. #Just try to make things look more-or less ok: if nsubplots <= 1 - mplot.ncolumns = 1 + mplot.layout[:ncolumns] = 1 elseif nsubplots <= 4 - mplot.ncolumns = 2 + mplot.layout[:ncolumns] = 2 elseif nsubplots <= 6 - mplot.ncolumns = 3 + mplot.layout[:ncolumns] = 3 elseif nsubplots <= 12 - mplot.ncolumns = 4 + mplot.layout[:ncolumns] = 4 else - mplot.ncolumns = 5 + mplot.layout[:ncolumns] = 5 end for series in plt.series_list @@ -446,7 +445,7 @@ function _update_min_padding!(sp::Subplot{InspectDRBackend}) 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)) + bb = InspectDR.plotbounds(plot.layout.values, 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?? @@ -468,7 +467,7 @@ function _update_plot_object(plt::Plot{InspectDRBackend}) for (i, sp) in enumerate(plt.subplots) graphbb = _inspectdr_to_pixels(plotarea(sp)) plot = mplot.subplots[i] - plot.plotbb = InspectDR.plotbounds(plot.layout, graphbb) + plot.plotbb = InspectDR.plotbounds(plot.layout.values, graphbb) end gplot = _inspectdr_getgui(plt.o) From 53ae91504472397bd65dc6441795a02d7070716e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Jun 2017 11:59:27 +0200 Subject: [PATCH 201/720] changed wkhtmltox link --- test/install_wkhtmltoimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_wkhtmltoimage.sh b/test/install_wkhtmltoimage.sh index 061cf606..d4326cc3 100755 --- a/test/install_wkhtmltoimage.sh +++ b/test/install_wkhtmltoimage.sh @@ -6,7 +6,7 @@ sudo apt-get -qq update # sudo apt-get install -y wkhtmltopdf sudo apt-get install -y xfonts-75dpi xfonts-base -wget https://downloads.wkhtmltopdf.org/0.12/0.12.2/wkhtmltox-0.12.2_linux-precise-amd64.deb +wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.2.1/wkhtmltox-0.12.2.1_linux-precise-amd64.deb sudo dpkg -i wkhtmltox-0.12.2_linux-precise-amd64.deb # wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2/wkhtmltox-0.12.2_linux-trusty-amd64.deb # sudo dpkg -i wkhtmltox-0.12.2_linux-trusty-amd64.deb From bc7f5118eaaa79acf77e6a05bf5f5027104c0bb4 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Jun 2017 15:51:24 +0200 Subject: [PATCH 202/720] changed package name for dpkg --- test/install_wkhtmltoimage.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/install_wkhtmltoimage.sh b/test/install_wkhtmltoimage.sh index d4326cc3..dbdf4c90 100755 --- a/test/install_wkhtmltoimage.sh +++ b/test/install_wkhtmltoimage.sh @@ -7,7 +7,7 @@ sudo apt-get -qq update sudo apt-get install -y xfonts-75dpi xfonts-base wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.2.1/wkhtmltox-0.12.2.1_linux-precise-amd64.deb -sudo dpkg -i wkhtmltox-0.12.2_linux-precise-amd64.deb +sudo dpkg -i wkhtmltox-0.12.2.1_linux-precise-amd64.deb # wget http://download.gna.org/wkhtmltopdf/0.12/0.12.2/wkhtmltox-0.12.2_linux-trusty-amd64.deb # sudo dpkg -i wkhtmltox-0.12.2_linux-trusty-amd64.deb wkhtmltoimage http://www.google.com test.png From 027ce58655dc022b5a1f8388ee0e7d1daa484578 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 14 Jun 2017 13:20:03 +0200 Subject: [PATCH 203/720] avoid negative heatmap edges for log axis on gr and pyplot --- src/backends/gr.jl | 2 +- src/backends/pyplot.jl | 2 +- src/utils.jl | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index feb2e5eb..879af59c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -585,7 +585,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if st == :heatmap outside_ticks = true - x, y = heatmap_edges(series[:x]), heatmap_edges(series[:y]) + x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale]) expand_extrema!(sp[:xaxis], x) expand_extrema!(sp[:yaxis], y) data_lims = gr_xy_axislims(sp) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index f7ca62ff..152626ea 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -768,7 +768,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end if st == :heatmap - x, y, z = heatmap_edges(x), heatmap_edges(y), transpose_z(series, z.surf) + x, y, z = heatmap_edges(x, sp[:xaxis][:scale]), heatmap_edges(y, sp[:yaxis][:scale]), transpose_z(series, z.surf) expand_extrema!(sp[:xaxis], x) expand_extrema!(sp[:yaxis], y) diff --git a/src/utils.jl b/src/utils.jl index d49b1fc7..2b0720fe 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -332,11 +332,24 @@ Base.first(x::Symbol) = x sortedkeys(d::Dict) = sort(collect(keys(d))) + +const _scale_base = Dict{Symbol, Real}( + :log10 => 10, + :log2 => 2, + :ln => e, +) + "create an (n+1) list of the outsides of heatmap rectangles" -function heatmap_edges(v::AVec) +function heatmap_edges(v::AVec, scale::Symbol = :identity) vmin, vmax = ignorenan_extrema(v) - extra = 0.5 * (vmax-vmin) / (length(v)-1) - vcat(vmin-extra, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra) + extra_min = extra_max = 0.5 * (vmax-vmin) / (length(v)-1) + if scale in _logScales + vmin > 0 || error("The axis values must be positive for a $scale scale") + while vmin - extra_min <= 0 + extra_min /= _scale_base[scale] + end + end + vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max) end From 33327d39926c1716c4c55d20498ec326cdd9ce5c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Jun 2017 17:45:20 +0200 Subject: [PATCH 204/720] allow turning off the colorbar for heatmap, contour and surface --- src/backends/plotly.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 4f3c956c..b7520e23 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -479,6 +479,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:type] = "heatmap" # d_out[:x], d_out[:y], d_out[:z] = series[:x], series[:y], transpose_z(series, series[:z].surf, false) d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) + d_out[:showscale] = sp[:legend] != :none elseif st == :contour d_out[:type] = "contour" @@ -487,6 +488,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:ncontours] = series[:levels] d_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines") d_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha]) + d_out[:showscale] = sp[:legend] != :none elseif st in (:surface, :wireframe) d_out[:type] = "surface" @@ -504,6 +506,7 @@ function plotly_series(plt::Plot, series::Series) if series[:fill_z] != nothing d_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z]) end + d_out[:showscale] = sp[:legend] != :none end elseif st == :pie From b091d95eb2af94fc689a13e6a1f4d31ba46d99b2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Jun 2017 17:56:47 +0200 Subject: [PATCH 205/720] turn off colorbar for wireframe --- src/backends/plotly.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b7520e23..c9cd8e22 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -501,6 +501,7 @@ function plotly_series(plt::Plot, series::Series) :highlightwidth => series[:linewidth], ) d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines) + d_out[:showscale] = false else d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) if series[:fill_z] != nothing From 47c51b28c17e0f02c60daec9256fbfa55b3f9cf1 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Mon, 19 Jun 2017 18:06:08 -0700 Subject: [PATCH 206/720] gr: heatmaps now respect xlim/ylim specifications Fixes https://github.com/JuliaPlots/Plots.jl/issues/942 --- src/backends/gr.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index feb2e5eb..4d5d3dd4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -886,7 +886,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, blue(c) * 255) << 16 + round(Int, green(c) * 255) << 8 + round(Int, red(c) * 255) ), colors) - GR.drawimage(xmin, xmax, ymax, ymin, length(x), length(y), rgba) + w, h = length(x), length(y) + GR.drawimage(0.5, w + 0.5, h + 0.5, 0.5, w, h, rgba) cmap && gr_colorbar(sp) elseif st in (:path3d, :scatter3d) From e35b2ec3ff9af6e717a290b5a7bc507a9b3ff6c3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 22 Jun 2017 18:51:03 +0200 Subject: [PATCH 207/720] replace deprecated DateTime convert methods --- src/recipes.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 64dd2c00..ce3533eb 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -970,11 +970,11 @@ abline!(args...; kw...) = abline!(current(), args...; kw...) # ------------------------------------------------- # Dates -dateformatter(dt) = string(convert(Date, dt)) -datetimeformatter(dt) = string(convert(DateTime, dt)) +dateformatter(dt) = string(Date(Dates.UTD(dt))) +datetimeformatter(dt) = string(DateTime(Dates.UTM(dt))) -@recipe f(::Type{Date}, dt::Date) = (dt -> convert(Int, dt), dateformatter) -@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> convert(Int, dt), datetimeformatter) +@recipe f(::Type{Date}, dt::Date) = (dt -> Dates.value(dt), dateformatter) +@recipe f(::Type{DateTime}, dt::DateTime) = (dt -> Dates.value(dt), datetimeformatter) # ------------------------------------------------- # Complex Numbers From 356a5b6136ab187814b2c51ade987a2d2c483713 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 22 Jun 2017 12:56:41 -0700 Subject: [PATCH 208/720] gr: fixed heatmap bug --- src/backends/gr.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 4d5d3dd4..8ef80de0 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -873,6 +873,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) cmap && gr_colorbar(sp) elseif st == :heatmap + xmin, xmax, ymin, ymax = data_lims zmin, zmax = gr_lims(zaxis, true) clims = sp[:clims] if is_2tuple(clims) @@ -887,7 +888,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, green(c) * 255) << 8 + round(Int, red(c) * 255) ), colors) w, h = length(x), length(y) - GR.drawimage(0.5, w + 0.5, h + 0.5, 0.5, w, h, rgba) + GR.drawimage(xmin - 0.5 * (xmax - xmin) / (w - 1), + xmax + 0.5 * (xmax - xmin) / (w - 1), + ymax + 0.5 * (ymax - ymin) / (h - 1), + ymin - 0.5 * (ymax - ymin) / (h - 1), w, h, rgba) cmap && gr_colorbar(sp) elseif st in (:path3d, :scatter3d) From 46ae505bab3ecd0ed770107935471eefe6d079a5 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 22 Jun 2017 15:31:13 -0700 Subject: [PATCH 209/720] gr: implemented "old" heatmap behaviour --- src/backends/gr.jl | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 8ef80de0..b9a09d61 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -544,6 +544,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) viewport_plotarea[:] = gr_viewport_from_bbox(sp, plotarea(sp), w, h, viewport_canvas) # get data limits data_lims = gr_xy_axislims(sp) + xy_lims = data_lims ratio = sp[:aspect_ratio] if ratio != :none @@ -586,6 +587,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st == :heatmap outside_ticks = true x, y = heatmap_edges(series[:x]), heatmap_edges(series[:y]) + xy_lims = x[1], x[end], y[1], y[end] expand_extrema!(sp[:xaxis], x) expand_extrema!(sp[:yaxis], y) data_lims = gr_xy_axislims(sp) @@ -873,7 +875,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) cmap && gr_colorbar(sp) elseif st == :heatmap - xmin, xmax, ymin, ymax = data_lims + xmin, xmax, ymin, ymax = xy_lims zmin, zmax = gr_lims(zaxis, true) clims = sp[:clims] if is_2tuple(clims) @@ -888,10 +890,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, green(c) * 255) << 8 + round(Int, red(c) * 255) ), colors) w, h = length(x), length(y) - GR.drawimage(xmin - 0.5 * (xmax - xmin) / (w - 1), - xmax + 0.5 * (xmax - xmin) / (w - 1), - ymax + 0.5 * (ymax - ymin) / (h - 1), - ymin - 0.5 * (ymax - ymin) / (h - 1), w, h, rgba) + GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) cmap && gr_colorbar(sp) elseif st in (:path3d, :scatter3d) From 2f1c70e49f1107d309aa0a6ce60cd80bde28426b Mon Sep 17 00:00:00 2001 From: Christina Lee Date: Wed, 28 Jun 2017 11:42:16 -0700 Subject: [PATCH 210/720] fixing deprecation warning --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index ce3533eb..f5cb9b73 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -703,7 +703,7 @@ end function error_coords(xorig, yorig, ebar) # init empty x/y, and zip errors if passed Tuple{Vector,Vector} - x, y = Array(float_extended_type(xorig), 0), Array(Float64, 0) + x, y = Array{float_extended_type(xorig)}(0), Array{Float64}(0) # for each point, create a line segment from the bottom to the top of the errorbar for i = 1:max(length(xorig), length(yorig)) xi = _cycle(xorig, i) From d671ccd6ba7089ff65d44226b1f714d0cb5d7c6f Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Thu, 8 Jun 2017 15:23:39 +0200 Subject: [PATCH 211/720] better juno integration --- REQUIRE | 1 + src/Plots.jl | 4 ++- src/output.jl | 73 ++++++++++++++++++++++++--------------------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/REQUIRE b/REQUIRE index 44e1623d..30e92d35 100644 --- a/REQUIRE +++ b/REQUIRE @@ -11,3 +11,4 @@ Showoff StatsBase 0.14.0 JSON NaNMath +Requires diff --git a/src/Plots.jl b/src/Plots.jl index a23d6a8d..9e2fa598 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -242,8 +242,10 @@ end const CURRENT_BACKEND = CurrentBackend(:none) function __init__() + # for compatibility with Requires.jl: + @init + setup_ijulia() - setup_atom() if isdefined(Main, :PLOTS_DEFAULTS) for (k,v) in Main.PLOTS_DEFAULTS diff --git a/src/output.jl b/src/output.jl index 814f8884..bd444ba0 100644 --- a/src/output.jl +++ b/src/output.jl @@ -278,48 +278,45 @@ end # --------------------------------------------------------- # Atom PlotPane # --------------------------------------------------------- +using Requires +@require Juno begin + import Hiccup, Media + Media.media(Plot, Media.Plot) -function setup_atom() - if isatom() - @eval import Atom, Media - Media.media(Plot, Media.Plot) + # default text/plain so it doesn't complain + function Base.show{B}(io::IO, ::MIME"text/plain", plt::Plot{B}) + print(io, "Plot{$B}()") + end - # default text/plain so it doesn't complain - function Base.show{B}(io::IO, ::MIME"text/plain", plt::Plot{B}) - print(io, "Plot{$B}()") + function Juno.render(e::Juno.Editor, plt::Plot) + Juno.render(e, nothing) + end + + if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") + # this is like "display"... sends an html div with the plot to the PlotPane + function Juno.render(pane::Juno.PlotPane, plt::Plot) + # temporarily overwrite size to be Atom.plotsize + sz = plt[:size] + plt[:size] = Juno.plotsize() + Juno.render(pane, Hiccup.div(".fill", HTML(stringmime(MIME("text/html"), plt)))) + plt[:size] = sz end - - function Media.render(e::Atom.Editor, plt::Plot) - Media.render(e, nothing) - end - - if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") - # this is like "display"... sends an html div with the plot to the PlotPane - function Media.render(pane::Atom.PlotPane, plt::Plot) - # temporarily overwrite size to be Atom.plotsize - sz = plt[:size] - plt[:size] = Juno.plotsize() - 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) - display(Plots.PlotsDisplay(), plt) - s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." - Media.render(pane, Atom.div(Atom.HTML(s))) - end - end - - # special handling for plotly... use PlotsDisplay - function Media.render(pane::Atom.PlotPane, plt::Plot{PlotlyBackend}) + # special handling for PlotlyJS + function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) display(Plots.PlotsDisplay(), plt) - s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." - Media.render(pane, Atom.div(Atom.HTML(s))) + end + else + function Juno.render(pane::Juno.PlotPane, plt::Plot) + display(Plots.PlotsDisplay(), plt) + s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." + Juno.render(pane, Hiccup.div(HTML(s))) end end + + # special handling for plotly... use PlotsDisplay + function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend}) + display(Plots.PlotsDisplay(), plt) + s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." + Juno.render(pane, Hiccup.div(HTML(s))) + end end From 5e5f23b5e5776266566bb95955ed00643dae3b3c Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Fri, 16 Jun 2017 15:26:30 +0200 Subject: [PATCH 212/720] fix world age error --- src/backends.jl | 6 +++--- src/output.jl | 16 +++++++--------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 19a9c6ea..9248d05b 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -135,7 +135,7 @@ function pickDefaultBackend() Pkg.installed(env_default) # this will error if not installed sym = Symbol(lowercase(env_default)) if haskey(_backendType, sym) - return backend(sym) + return @eval backend($sym) else warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not a valid backend package. Choose from:\n\t", join(sort(_backends), "\n\t")) @@ -150,12 +150,12 @@ function pickDefaultBackend() # features, speed, and robustness for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize") if Pkg.installed(pkgstr) != nothing - return backend(Symbol(lowercase(pkgstr))) + return @eval backend(Symbol(lowercase($pkgstr))) end end # the default if nothing else is installed - backend(:plotly) + @eval backend(:plotly) end diff --git a/src/output.jl b/src/output.jl index bd444ba0..a838a542 100644 --- a/src/output.jl +++ b/src/output.jl @@ -283,22 +283,20 @@ using Requires import Hiccup, Media Media.media(Plot, Media.Plot) - # default text/plain so it doesn't complain - function Base.show{B}(io::IO, ::MIME"text/plain", plt::Plot{B}) - print(io, "Plot{$B}()") - end - function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) end if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") - # this is like "display"... sends an html div with the plot to the PlotPane function Juno.render(pane::Juno.PlotPane, plt::Plot) # temporarily overwrite size to be Atom.plotsize sz = plt[:size] + jsize = Juno.plotsize() + jsize[1] == 0 && (jsize[1] = 400) + jsize[2] == 0 && (jsize[2] = 500) + plt[:size] = Juno.plotsize() - Juno.render(pane, Hiccup.div(".fill", HTML(stringmime(MIME("text/html"), plt)))) + Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz end # special handling for PlotlyJS @@ -309,7 +307,7 @@ using Requires function Juno.render(pane::Juno.PlotPane, plt::Plot) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." - Juno.render(pane, Hiccup.div(HTML(s))) + Juno.render(pane, HTML(s)) end end @@ -317,6 +315,6 @@ using Requires function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend}) display(Plots.PlotsDisplay(), plt) s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." - Juno.render(pane, Hiccup.div(HTML(s))) + Juno.render(pane, HTML(s)) end end From de043eeaa2f975955f5602e2dc81e31d090ba4e8 Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Wed, 5 Jul 2017 17:12:39 -0400 Subject: [PATCH 213/720] switch from FixedSizeArrays to StaticArrays.FixedSizeArrays --- REQUIRE | 2 +- src/Plots.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/REQUIRE b/REQUIRE index 44e1623d..3d6ae3c9 100644 --- a/REQUIRE +++ b/REQUIRE @@ -4,7 +4,7 @@ RecipesBase 0.2.0 PlotUtils 0.4.1 PlotThemes 0.1.3 Reexport -FixedSizeArrays +StaticArrays 0.5 FixedPointNumbers 0.3 Measures Showoff diff --git a/src/Plots.jl b/src/Plots.jl index a23d6a8d..f5a8df9a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -3,7 +3,7 @@ __precompile__(true) module Plots using Reexport -using FixedSizeArrays +using StaticArrays.FixedSizeArrays @reexport using RecipesBase import RecipesBase: plot, animate using Base.Meta From 02ddbc8381043851e78bc27cef9c2012919f0ad1 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 11 Jul 2017 09:04:35 +0200 Subject: [PATCH 214/720] fix glvisualize backend for 0.6 --- src/Plots.jl | 3 +++ src/backends/glvisualize.jl | 41 +++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index f5a8df9a..71fa2ec3 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -3,7 +3,10 @@ __precompile__(true) module Plots using Reexport + +import StaticArrays using StaticArrays.FixedSizeArrays + @reexport using RecipesBase import RecipesBase: plot, animate using Base.Meta diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index ea42c598..128d439e 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -58,7 +58,7 @@ const _glvisualize_scale = [:identity, :ln, :log2, :log10] function _initialize_backend(::GLVisualizeBackend; kw...) @eval begin import GLVisualize, GeometryTypes, Reactive, GLAbstraction, GLWindow, Contour - import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle + import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle, Point, Vec import FileIO, Images export GLVisualize import Reactive: Signal @@ -173,12 +173,12 @@ function gl_marker(shape) shape end function gl_marker(shape::Shape) - points = Point2f0[Vec{2,Float32}(p) for p in zip(shape.x, shape.y)] + points = Point2f0[GeometryTypes.Vec{2, Float32}(p) for p in zip(shape.x, shape.y)] bb = GeometryTypes.AABB(points) mini, maxi = minimum(bb), maximum(bb) w3 = maxi-mini origin, width = Point2f0(mini[1], mini[2]), Point2f0(w3[1], w3[2]) - map!(p -> ((p - origin) ./ width) - 0.5f0, points) # normalize and center + map!(p -> ((p - origin) ./ width) - 0.5f0, points, points) # normalize and center GeometryTypes.GLNormalMesh(points) end # create a marker/shape type @@ -212,13 +212,13 @@ function extract_limits(sp, d, kw_args) nothing end -to_vec{T <: FixedVector}(::Type{T}, vec::T) = vec -to_vec{T <: FixedVector}(::Type{T}, s::Number) = T(s) +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vec::T) = vec +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, s::Number) = T(s) -to_vec{T <: FixedVector{2}}(::Type{T}, vec::FixedVector{3}) = T(vec[1], vec[2]) -to_vec{T <: FixedVector{3}}(::Type{T}, vec::FixedVector{2}) = T(vec[1], vec[2], 0) +to_vec{T <: StaticArrays.StaticVector{2}}(::Type{T}, vec::StaticArrays.StaticVector{3}) = T(vec[1], vec[2]) +to_vec{T <: StaticArrays.StaticVector{3}}(::Type{T}, vec::StaticArrays.StaticVector{2}) = T(vec[1], vec[2], 0) -to_vec{T <: FixedVector}(::Type{T}, vecs::AbstractVector) = map(x-> to_vec(T, x), vecs) +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vecs::AbstractVector) = map(x-> to_vec(T, x), vecs) function extract_marker(d, kw_args) dim = Plots.is3d(d) ? 3 : 2 @@ -274,7 +274,7 @@ function extract_surface(d) map(_extract_surface, (d[:x], d[:y], d[:z])) end function topoints{P}(::Type{P}, array) - P[x for x in zip(array...)] + [P(x) for x in zip(array...)] end function extract_points(d) dim = is3d(d) ? 3 : 2 @@ -576,8 +576,10 @@ end function align_offset(startpos, lastpos, atlas, rscale, font, align) xscale, yscale = GLVisualize.glyph_scale!('X', rscale) - xmove = (lastpos-startpos)[1]+xscale - if align == :top + xmove = (lastpos-startpos)[1] + xscale + if isa(align, GeometryTypes.Vec) + return -Vec2f0(xmove, yscale) .* align + elseif align == :top return -Vec2f0(xmove/2f0, yscale) elseif align == :right return -Vec2f0(xmove, yscale/2f0) @@ -586,11 +588,6 @@ function align_offset(startpos, lastpos, atlas, rscale, font, align) end end -function align_offset(startpos, lastpos, atlas, rscale, font, align::Vec) - xscale, yscale = GLVisualize.glyph_scale!('X', rscale) - xmove = (lastpos-startpos)[1] + xscale - return -Vec2f0(xmove, yscale) .* align -end function alignment2num(x::Symbol) (x in (:hcenter, :vcenter)) && return 0.5 @@ -638,7 +635,7 @@ function draw_ticks( position = GLVisualize.calc_position(str, startpos, sz, font, atlas) offset = GLVisualize.calc_offset(str, sz, font, atlas) alignoff = align_offset(startpos, last(position), atlas, sz, font, align) - map!(position) do pos + map!(position, position) do pos pos .+ alignoff end append!(positions, position) @@ -660,7 +657,7 @@ function glvisualize_text(position, text, kw_args) offset = GLVisualize.calc_offset(text.str, rscale, font, atlas) alignoff = align_offset(startpos, last(position), atlas, rscale, font, text_align) - map!(position) do pos + map!(position, position) do pos pos .+ alignoff end kw_args[:position] = position @@ -1122,7 +1119,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) anns = series[:series_annotations] for (x, y, str, font) in EachAnn(anns, d[:x], d[:y]) txt_args = Dict{Symbol, Any}(:model => eye(GLAbstraction.Mat4f0)) - x, y = Reactive.value(model_m) * Vec{4, Float32}(x, y, 0, 1) + x, y = Reactive.value(model_m) * GeometryTypes.Vec{4, Float32}(x, y, 0, 1) extract_font(font, txt_args) t = glvisualize_text(Point2f0(x, y), PlotText(str, font), txt_args) GLVisualize._view(t, sp_screen, camera = :perspective) @@ -1309,8 +1306,8 @@ function gl_contour(x, y, z, kw_args) if kw_args[:fillrange] != nothing delete!(kw_args, :intensity) - I = GLVisualize.Intensity{1, Float32} - main = I[z[j,i] for i=1:size(z, 2), j=1:size(z, 1)] + I = GLVisualize.Intensity{Float32} + main = [I(z[j,i]) for i=1:size(z, 2), j=1:size(z, 1)] return visualize(main, Style(:default), kw_args) else @@ -1342,7 +1339,7 @@ function gl_heatmap(x,y,z, kw_args) get!(kw_args, :color_norm, Vec2f0(ignorenan_extrema(z))) get!(kw_args, :color_map, Plots.make_gradient(cgrad())) delete!(kw_args, :intensity) - I = GLVisualize.Intensity{1, Float32} + I = GLVisualize.Intensity{Float32} heatmap = I[z[j,i] for i=1:size(z, 2), j=1:size(z, 1)] tex = GLAbstraction.Texture(heatmap, minfilter=:nearest) kw_args[:stroke_width] = 0f0 From 409cf2c6309ab5102c94e40ff7fc2d3a9b31c006 Mon Sep 17 00:00:00 2001 From: JackDevine Date: Wed, 12 Jul 2017 17:37:37 +1200 Subject: [PATCH 215/720] Fixed a deprecation warning on the pyplot backend The follwing code created a deprecation warining: using Plots; pyplot() plot([1,2,3,4], [2,3,4,5], yscale=:log10) --- 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 f7ca62ff..251b6377 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -926,7 +926,7 @@ function py_compute_axis_minval(axis::Axis) for series in series_list(sp) v = series.d[axis[:letter]] if !isempty(v) - minval = NaNMath.min(minval, ignorenan_minimum(abs(v))) + minval = NaNMath.min(minval, ignorenan_minimum(abs.(v))) end end end From c385035ac58fe5bb323f9c0a2f2e8a2686f8c6d4 Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Wed, 12 Jul 2017 10:38:15 +0200 Subject: [PATCH 216/720] handle ijulia with requires and properly check if juno/ijulia are actually used and not just loaded --- src/Plots.jl | 2 -- src/output.jl | 99 ++++++++++++++++++++++++++------------------------- 2 files changed, 50 insertions(+), 51 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 9e2fa598..d31d0258 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -245,8 +245,6 @@ function __init__() # for compatibility with Requires.jl: @init - setup_ijulia() - if isdefined(Main, :PLOTS_DEFAULTS) for (k,v) in Main.PLOTS_DEFAULTS default(k, v) diff --git a/src/output.jl b/src/output.jl index a838a542..fe46d992 100644 --- a/src/output.jl +++ b/src/output.jl @@ -250,71 +250,72 @@ end const _ijulia_output = String["text/html"] -function setup_ijulia() - # override IJulia inline display - if isijulia() - @eval begin - import IJulia - export set_ijulia_output - function set_ijulia_output(mimestr::AbstractString) - # info("Setting IJulia output format to $mimestr") - global _ijulia_output - _ijulia_output[1] = mimestr - end - function IJulia.display_dict(plt::Plot) - global _ijulia_output - Dict{String, String}(_ijulia_output[1] => sprint(show, _ijulia_output[1], plt)) - end +using Requires +@require IJulia begin + if IJulia.inited + export set_ijulia_output - # default text/plain passes to html... handles Interact issues - function Base.show(io::IO, m::MIME"text/plain", plt::Plot) - show(io, MIME("text/html"), plt) - end + function set_ijulia_output(mimestr::AbstractString) + # info("Setting IJulia output format to $mimestr") + global _ijulia_output + _ijulia_output[1] = mimestr end - @eval set_ijulia_output("text/html") + function IJulia.display_dict(plt::Plot) + global _ijulia_output + Dict{String, String}(_ijulia_output[1] => sprint(show, _ijulia_output[1], plt)) + end + + # default text/plain passes to html... handles Interact issues + function Base.show(io::IO, m::MIME"text/plain", plt::Plot) + show(io, MIME("text/html"), plt) + end + + set_ijulia_output("text/html") end end # --------------------------------------------------------- # Atom PlotPane # --------------------------------------------------------- -using Requires @require Juno begin import Hiccup, Media - Media.media(Plot, Media.Plot) - function Juno.render(e::Juno.Editor, plt::Plot) - Juno.render(e, nothing) - end + if Juno.isactive() + Media.media(Plot, Media.Plot) - if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") - function Juno.render(pane::Juno.PlotPane, plt::Plot) - # temporarily overwrite size to be Atom.plotsize - sz = plt[:size] - jsize = Juno.plotsize() - jsize[1] == 0 && (jsize[1] = 400) - jsize[2] == 0 && (jsize[2] = 500) - - plt[:size] = Juno.plotsize() - Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) - plt[:size] = sz + function Juno.render(e::Juno.Editor, plt::Plot) + Juno.render(e, nothing) end - # special handling for PlotlyJS - function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) - display(Plots.PlotsDisplay(), plt) + + if get(ENV, "PLOTS_USE_ATOM_PLOTPANE", true) in (true, 1, "1", "true", "yes") + function Juno.render(pane::Juno.PlotPane, plt::Plot) + # temporarily overwrite size to be Atom.plotsize + sz = plt[:size] + jsize = Juno.plotsize() + jsize[1] == 0 && (jsize[1] = 400) + jsize[2] == 0 && (jsize[2] = 500) + + plt[:size] = Juno.plotsize() + Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) + plt[:size] = sz + end + # special handling for PlotlyJS + function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) + display(Plots.PlotsDisplay(), plt) + end + else + function Juno.render(pane::Juno.PlotPane, plt::Plot) + display(Plots.PlotsDisplay(), plt) + s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." + Juno.render(pane, HTML(s)) + end end - else - function Juno.render(pane::Juno.PlotPane, plt::Plot) + + # special handling for plotly... use PlotsDisplay + function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend}) display(Plots.PlotsDisplay(), plt) - s = "PlotPane turned off. Unset ENV[\"PLOTS_USE_ATOM_PLOTPANE\"] and restart Julia to enable it." + s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." Juno.render(pane, HTML(s)) end end - - # special handling for plotly... use PlotsDisplay - function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyBackend}) - display(Plots.PlotsDisplay(), plt) - s = "PlotPane turned off. The plotly backend cannot render in the PlotPane due to javascript issues. Plotlyjs is similar to plotly and is compatible with the plot pane." - Juno.render(pane, HTML(s)) - end end From 9cf246a03e51269c11fe1f16dc2516016447cb3b Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Wed, 12 Jul 2017 10:40:26 +0200 Subject: [PATCH 217/720] fix juno plot sizing fallback --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index fe46d992..bdf60d9e 100644 --- a/src/output.jl +++ b/src/output.jl @@ -295,7 +295,7 @@ end jsize[1] == 0 && (jsize[1] = 400) jsize[2] == 0 && (jsize[2] = 500) - plt[:size] = Juno.plotsize() + plt[:size] = jsize Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz end From aec30301a1f0ae3424b1c36925318d89bb95ab5f Mon Sep 17 00:00:00 2001 From: Pearl Li Date: Wed, 12 Jul 2017 16:19:29 -0400 Subject: [PATCH 218/720] Add fillrange for Plotly --- src/backends/plotly.jl | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index c9cd8e22..914a1f0a 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -435,6 +435,7 @@ function plotly_series(plt::Plot, series::Series) isscatter = st in (:scatter, :scatter3d, :scattergl) hasmarker = isscatter || series[:markershape] != :none hasline = st in (:path, :path3d) + hasfillrange = st in (:path, :scatter, :scattergl) && isa(series[:fillrange], AbstractVector) # for surface types, set the data if st in (:heatmap, :contour, :surface, :wireframe) @@ -461,8 +462,11 @@ function plotly_series(plt::Plot, series::Series) if series[:fillrange] == true || series[:fillrange] == 0 d_out[:fill] = "tozeroy" d_out[:fillcolor] = rgba_string(series[:fillcolor]) + elseif isa(series[:fillrange], AbstractVector) + d_out[:fill] = "tonexty" + d_out[:fillcolor] = rgba_string(series[:fillcolor]) elseif !(series[:fillrange] in (false, nothing)) - warn("fillrange ignored... plotly only supports filling to zero. fillrange: $(series[:fillrange])") + warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])") end d_out[:x], d_out[:y] = x, y @@ -576,7 +580,18 @@ function plotly_series(plt::Plot, series::Series) plotly_polar!(d_out, series) plotly_hover!(d_out, series[:hover]) - [d_out] + if hasfillrange + # if hasfillrange is true, return two dictionaries (one for original + # series, one for series being filled to) instead of one + d_out_fillrange = copy(d_out) + d_out_fillrange[:y] = series[:fillrange] + delete!(d_out_fillrange, :fill) + delete!(d_out_fillrange, :fillcolor) + + return [d_out_fillrange, d_out] + else + return [d_out] + end end function plotly_series_shapes(plt::Plot, series::Series) From 2a0d5a0a039498d675a86e7e48e67f93ce835745 Mon Sep 17 00:00:00 2001 From: Pearl Li Date: Wed, 12 Jul 2017 17:04:01 -0400 Subject: [PATCH 219/720] Hide legend entry for series being filled to --- src/backends/plotly.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 914a1f0a..440884a9 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -585,6 +585,7 @@ function plotly_series(plt::Plot, series::Series) # series, one for series being filled to) instead of one d_out_fillrange = copy(d_out) d_out_fillrange[:y] = series[:fillrange] + d_out_fillrange[:showlegend] = false delete!(d_out_fillrange, :fill) delete!(d_out_fillrange, :fillcolor) From 33e97ee49be209f034d23e3ab80867e9c8637a53 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 14 Jul 2017 09:12:17 -0500 Subject: [PATCH 220/720] Update to newer Images --- src/backends/glvisualize.jl | 8 ++------ src/examples.jl | 4 ++-- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 128d439e..8e61860d 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -66,9 +66,8 @@ function _initialize_backend(::GLVisualizeBackend; kw...) import GLVisualize: visualize import Plots.GL import UnicodeFun - Plots.slice_arg(img::Images.AbstractImage, idx::Int) = img + Plots.slice_arg{C<:Colorant}(img::Matrix{C}, idx::Int) = img is_marker_supported(::GLVisualizeBackend, shape::GLVisualize.AllPrimitives) = true - is_marker_supported{Img<:Images.AbstractImage}(::GLVisualizeBackend, shape::Union{Vector{Img}, Img}) = true is_marker_supported{C<:Colorant}(::GLVisualizeBackend, shape::Union{Vector{Matrix{C}}, Matrix{C}}) = true is_marker_supported(::GLVisualizeBackend, shape::Shape) = true const GL = Plots @@ -1145,10 +1144,7 @@ function _show(io::IO, ::MIME"image/png", plt::Plot{GLVisualizeBackend}) GLWindow.render_frame(GLWindow.rootscreen(plt.o)) GLWindow.swapbuffers(plt.o) buff = GLWindow.screenbuffer(plt.o) - png = Images.Image(map(RGB{U8}, buff), - colorspace = "sRGB", - spatialorder = ["y", "x"] - ) + png = map(RGB{U8}, buff) FileIO.save(FileIO.Stream(FileIO.DataFormat{:PNG}, io), png) end diff --git a/src/examples.jl b/src/examples.jl index 6702832c..a9b86960 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -66,8 +66,8 @@ PlotExample("Global", PlotExample("Images", "Plot an image. y-axis is set to flipped", [:(begin - import Images - img = Images.load(Pkg.dir("PlotReferenceImages","Plots","pyplot","0.7.0","ref1.png")) + import FileIO + img = FileIO.load(Pkg.dir("PlotReferenceImages","Plots","pyplot","0.7.0","ref1.png")) plot(img) end)] ), From 96bd0bb46c4e8908caef3b09f2788484dd2f7b62 Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 14 Jul 2017 10:01:52 -0500 Subject: [PATCH 221/720] Fix some errors/depwarns --- src/backends/glvisualize.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 8e61860d..3484131b 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -788,7 +788,7 @@ function gl_bar(d, kw_args) fillto = 0 end # create the bar shapes by adding x/y segments - positions, scales = Array(Point2f0, ny), Array(Vec2f0, ny) + positions, scales = Array{Point2f0}(ny), Array{Vec2f0}(ny) m = Reactive.value(kw_args[:model]) sx, sy = m[1,1], m[2,2] for i=1:ny @@ -939,7 +939,7 @@ function scale_for_annotations!(series::Series, scaletype::Symbol = :pixels) # we use baseshape to overwrite the markershape attribute # with a list of custom shapes for each msw, msh = anns.scalefactor - offsets = Array(Vec2f0, length(anns.strs)) + offsets = Array{Vec2f0}(length(anns.strs)) series[:markersize] = map(1:length(anns.strs)) do i str = _cycle(anns.strs, i) # get the width and height of the string (in mm) From bc7f6a6fac35f65319a106799f8b2ccdd702db9f Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Sat, 15 Jul 2017 11:40:11 +0200 Subject: [PATCH 222/720] circumvent warnings --- src/Plots.jl | 6 ++---- src/output.jl | 3 +++ 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index d31d0258..10e7bf6e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -241,10 +241,8 @@ end const CURRENT_BACKEND = CurrentBackend(:none) -function __init__() - # for compatibility with Requires.jl: - @init - +# for compatibility with Requires.jl: +@init begin if isdefined(Main, :PLOTS_DEFAULTS) for (k,v) in Main.PLOTS_DEFAULTS default(k, v) diff --git a/src/output.jl b/src/output.jl index bdf60d9e..cdb6777b 100644 --- a/src/output.jl +++ b/src/output.jl @@ -283,6 +283,9 @@ end if Juno.isactive() Media.media(Plot, Media.Plot) + + _show{B}(io::IO, m::MIME"text/plain", plt::Plot{B}) = show(io, m, plt) + function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) end From 95c60b9554effa3c5b13ec90080276a68390f121 Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Sat, 15 Jul 2017 12:01:00 +0200 Subject: [PATCH 223/720] unrecursify this definition --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index cdb6777b..06a049e5 100644 --- a/src/output.jl +++ b/src/output.jl @@ -284,7 +284,7 @@ end Media.media(Plot, Media.Plot) - _show{B}(io::IO, m::MIME"text/plain", plt::Plot{B}) = show(io, m, plt) + _show{B}(io::IO, m::MIME"text/plain", plt::Plot{B}) = print(io, "Plot{$B}()") function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) From 6d6619064492ab776d46ebae8d0cc13fac76231a Mon Sep 17 00:00:00 2001 From: Sebastian Pfitzner Date: Mon, 17 Jul 2017 15:16:20 +0200 Subject: [PATCH 224/720] no eval shenanigans --- src/backends.jl | 6 +++--- src/output.jl | 4 ---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 9248d05b..19a9c6ea 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -135,7 +135,7 @@ function pickDefaultBackend() Pkg.installed(env_default) # this will error if not installed sym = Symbol(lowercase(env_default)) if haskey(_backendType, sym) - return @eval backend($sym) + return backend(sym) else warn("You have set PLOTS_DEFAULT_BACKEND=$env_default but it is not a valid backend package. Choose from:\n\t", join(sort(_backends), "\n\t")) @@ -150,12 +150,12 @@ function pickDefaultBackend() # features, speed, and robustness for pkgstr in ("GR", "PyPlot", "PlotlyJS", "PGFPlots", "UnicodePlots", "InspectDR", "GLVisualize") if Pkg.installed(pkgstr) != nothing - return @eval backend(Symbol(lowercase($pkgstr))) + return backend(Symbol(lowercase(pkgstr))) end end # the default if nothing else is installed - @eval backend(:plotly) + backend(:plotly) end diff --git a/src/output.jl b/src/output.jl index 06a049e5..5c036fe7 100644 --- a/src/output.jl +++ b/src/output.jl @@ -224,10 +224,6 @@ if is_installed("FileIO") end end - - - - # function html_output_format(fmt) # if fmt == "png" # @eval function Base.show(io::IO, ::MIME"text/html", plt::Plot) From 155634ef34cdc761251033f9dfe959c0ebd8a153 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 2 Jul 2017 18:32:34 +0200 Subject: [PATCH 225/720] change gr legend marker for ribbon --- src/backends/gr.jl | 2 +- src/utils.jl | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 989a0751..a79cf62f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1049,7 +1049,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) should_add_to_legend(series) || continue st = series[:seriestype] gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - if st == :path && series[:fillrange] == nothing + if st == :path && (series[:fillrange] == nothing || has_ribbon(series)) GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) elseif st == :shape || series[:fillrange] != nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) diff --git a/src/utils.jl b/src/utils.jl index 2b0720fe..84d82ea5 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -493,10 +493,16 @@ function make_fillrange_from_ribbon(kw::KW) y, rib = kw[:y], kw[:ribbon] rib = wraptuple(rib) rib1, rib2 = -first(rib), last(rib) - kw[:ribbon] = nothing + # kw[:ribbon] = nothing kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2) end +# check if series has a ribbon +function has_ribbon(series::Series) + series[:ribbon] == nothing && return false + return series[:ribbon] > 0 +end + function get_sp_lims(sp::Subplot, letter::Symbol) axis_limits(sp[Symbol(letter, :axis)]) end From f66d8bed8fb5009a14cda72ca5ce53b9246316d1 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Tue, 11 Jul 2017 09:04:35 +0200 Subject: [PATCH 226/720] fix glvisualize backend for 0.6 --- src/Plots.jl | 3 +++ src/backends/glvisualize.jl | 41 +++++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 993fb246..3b87b433 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -3,7 +3,10 @@ __precompile__(true) module Plots using Reexport + +import StaticArrays using StaticArrays.FixedSizeArrays + @reexport using RecipesBase import RecipesBase: plot, animate using Base.Meta diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index ea42c598..128d439e 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -58,7 +58,7 @@ const _glvisualize_scale = [:identity, :ln, :log2, :log10] function _initialize_backend(::GLVisualizeBackend; kw...) @eval begin import GLVisualize, GeometryTypes, Reactive, GLAbstraction, GLWindow, Contour - import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle + import GeometryTypes: Point2f0, Point3f0, Vec2f0, Vec3f0, GLNormalMesh, SimpleRectangle, Point, Vec import FileIO, Images export GLVisualize import Reactive: Signal @@ -173,12 +173,12 @@ function gl_marker(shape) shape end function gl_marker(shape::Shape) - points = Point2f0[Vec{2,Float32}(p) for p in zip(shape.x, shape.y)] + points = Point2f0[GeometryTypes.Vec{2, Float32}(p) for p in zip(shape.x, shape.y)] bb = GeometryTypes.AABB(points) mini, maxi = minimum(bb), maximum(bb) w3 = maxi-mini origin, width = Point2f0(mini[1], mini[2]), Point2f0(w3[1], w3[2]) - map!(p -> ((p - origin) ./ width) - 0.5f0, points) # normalize and center + map!(p -> ((p - origin) ./ width) - 0.5f0, points, points) # normalize and center GeometryTypes.GLNormalMesh(points) end # create a marker/shape type @@ -212,13 +212,13 @@ function extract_limits(sp, d, kw_args) nothing end -to_vec{T <: FixedVector}(::Type{T}, vec::T) = vec -to_vec{T <: FixedVector}(::Type{T}, s::Number) = T(s) +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vec::T) = vec +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, s::Number) = T(s) -to_vec{T <: FixedVector{2}}(::Type{T}, vec::FixedVector{3}) = T(vec[1], vec[2]) -to_vec{T <: FixedVector{3}}(::Type{T}, vec::FixedVector{2}) = T(vec[1], vec[2], 0) +to_vec{T <: StaticArrays.StaticVector{2}}(::Type{T}, vec::StaticArrays.StaticVector{3}) = T(vec[1], vec[2]) +to_vec{T <: StaticArrays.StaticVector{3}}(::Type{T}, vec::StaticArrays.StaticVector{2}) = T(vec[1], vec[2], 0) -to_vec{T <: FixedVector}(::Type{T}, vecs::AbstractVector) = map(x-> to_vec(T, x), vecs) +to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vecs::AbstractVector) = map(x-> to_vec(T, x), vecs) function extract_marker(d, kw_args) dim = Plots.is3d(d) ? 3 : 2 @@ -274,7 +274,7 @@ function extract_surface(d) map(_extract_surface, (d[:x], d[:y], d[:z])) end function topoints{P}(::Type{P}, array) - P[x for x in zip(array...)] + [P(x) for x in zip(array...)] end function extract_points(d) dim = is3d(d) ? 3 : 2 @@ -576,8 +576,10 @@ end function align_offset(startpos, lastpos, atlas, rscale, font, align) xscale, yscale = GLVisualize.glyph_scale!('X', rscale) - xmove = (lastpos-startpos)[1]+xscale - if align == :top + xmove = (lastpos-startpos)[1] + xscale + if isa(align, GeometryTypes.Vec) + return -Vec2f0(xmove, yscale) .* align + elseif align == :top return -Vec2f0(xmove/2f0, yscale) elseif align == :right return -Vec2f0(xmove, yscale/2f0) @@ -586,11 +588,6 @@ function align_offset(startpos, lastpos, atlas, rscale, font, align) end end -function align_offset(startpos, lastpos, atlas, rscale, font, align::Vec) - xscale, yscale = GLVisualize.glyph_scale!('X', rscale) - xmove = (lastpos-startpos)[1] + xscale - return -Vec2f0(xmove, yscale) .* align -end function alignment2num(x::Symbol) (x in (:hcenter, :vcenter)) && return 0.5 @@ -638,7 +635,7 @@ function draw_ticks( position = GLVisualize.calc_position(str, startpos, sz, font, atlas) offset = GLVisualize.calc_offset(str, sz, font, atlas) alignoff = align_offset(startpos, last(position), atlas, sz, font, align) - map!(position) do pos + map!(position, position) do pos pos .+ alignoff end append!(positions, position) @@ -660,7 +657,7 @@ function glvisualize_text(position, text, kw_args) offset = GLVisualize.calc_offset(text.str, rscale, font, atlas) alignoff = align_offset(startpos, last(position), atlas, rscale, font, text_align) - map!(position) do pos + map!(position, position) do pos pos .+ alignoff end kw_args[:position] = position @@ -1122,7 +1119,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) anns = series[:series_annotations] for (x, y, str, font) in EachAnn(anns, d[:x], d[:y]) txt_args = Dict{Symbol, Any}(:model => eye(GLAbstraction.Mat4f0)) - x, y = Reactive.value(model_m) * Vec{4, Float32}(x, y, 0, 1) + x, y = Reactive.value(model_m) * GeometryTypes.Vec{4, Float32}(x, y, 0, 1) extract_font(font, txt_args) t = glvisualize_text(Point2f0(x, y), PlotText(str, font), txt_args) GLVisualize._view(t, sp_screen, camera = :perspective) @@ -1309,8 +1306,8 @@ function gl_contour(x, y, z, kw_args) if kw_args[:fillrange] != nothing delete!(kw_args, :intensity) - I = GLVisualize.Intensity{1, Float32} - main = I[z[j,i] for i=1:size(z, 2), j=1:size(z, 1)] + I = GLVisualize.Intensity{Float32} + main = [I(z[j,i]) for i=1:size(z, 2), j=1:size(z, 1)] return visualize(main, Style(:default), kw_args) else @@ -1342,7 +1339,7 @@ function gl_heatmap(x,y,z, kw_args) get!(kw_args, :color_norm, Vec2f0(ignorenan_extrema(z))) get!(kw_args, :color_map, Plots.make_gradient(cgrad())) delete!(kw_args, :intensity) - I = GLVisualize.Intensity{1, Float32} + I = GLVisualize.Intensity{Float32} heatmap = I[z[j,i] for i=1:size(z, 2), j=1:size(z, 1)] tex = GLAbstraction.Texture(heatmap, minfilter=:nearest) kw_args[:stroke_width] = 0f0 From e992930ff627e7d8880d04c82b0378fdbf00f7e6 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Thu, 20 Jul 2017 10:35:33 +0200 Subject: [PATCH 227/720] add contour as a dependency --- REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/REQUIRE b/REQUIRE index ff0b6755..6b96e23e 100644 --- a/REQUIRE +++ b/REQUIRE @@ -12,3 +12,4 @@ StatsBase 0.14.0 JSON NaNMath Requires +Contour From ccd26a6d42e07b7fcddf217312bb844cdeb9603c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 13:25:09 +0200 Subject: [PATCH 228/720] drop FactCheck in tests --- test/imgcomp.jl | 4 +-- test/runtests.jl | 82 +++++++++++++++++++++++------------------------- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index cd3b7058..1d4d3e05 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -15,7 +15,7 @@ end using Plots using StatPlots -using FactCheck +using Base.Test using Glob default(size=(500,300)) @@ -99,7 +99,7 @@ function image_comparison_facts(pkg::Symbol; for i in 1:length(Plots._examples) i in skip && continue if only == nothing || i in only - @fact @eval(image_comparison_tests(Symbol(String(Symbol($pkg))[7:end]), $i, debug=$debug, sigma=$sigma, eps=$eps)) |> success --> true + @test image_comparison_tests(pkg, i, debug=debug, sigma=sigma, eps=eps) |> success == true end end end diff --git a/test/runtests.jl b/test/runtests.jl index 75f4302c..ba8666ec 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -7,35 +7,35 @@ srand(1234) default(show=false, reuse=true) img_eps = isinteractive() ? 1e-2 : 10e-2 -facts("GR") do - @fact gr() --> Plots.GRBackend() - @fact backend() --> Plots.GRBackend() +@testset "GR" begin + @fact gr() == Plots.GRBackend() + @fact backend() == Plots.GRBackend() image_comparison_facts(:gr, eps=img_eps) end -facts("PyPlot") do - @fact pyplot() --> Plots.PyPlotBackend() - @fact backend() --> Plots.PyPlotBackend() +@testset "PyPlot" begin + @fact pyplot() == Plots.PyPlotBackend() + @fact backend() == Plots.PyPlotBackend() image_comparison_facts(:pyplot, eps=img_eps) end -facts("UnicodePlots") do - @fact unicodeplots() --> Plots.UnicodePlotsBackend() - @fact backend() --> Plots.UnicodePlotsBackend() +@testset "UnicodePlots" begin + @fact unicodeplots() == Plots.UnicodePlotsBackend() + @fact backend() == Plots.UnicodePlotsBackend() # lets just make sure it runs without error - @fact isa(plot(rand(10)), Plots.Plot) --> true + @fact isa(plot(rand(10)), Plots.Plot) == true end # The plotlyjs testimages return a connection error on travis: # connect: connection refused (ECONNREFUSED) -# facts("PlotlyJS") do -# @fact plotlyjs() --> Plots.PlotlyJSBackend() -# @fact backend() --> Plots.PlotlyJSBackend() +@testset "PlotlyJS" begin +# @fact plotlyjs() == Plots.PlotlyJSBackend() +# @fact backend() == Plots.PlotlyJSBackend() # # if is_linux() && isinteractive() # image_comparison_facts(:plotlyjs, @@ -53,9 +53,9 @@ end # ERROR: LoadError: InitError: Cannot open display: # in Gtk.GLib.GError(::Gtk.##229#230) at /home/travis/.julia/v0.5/Gtk/src/GLib/gerror.jl:17 -# facts("InspectDR") do -# @fact inspectdr() --> Plots.InspectDRBackend() -# @fact backend() --> Plots.InspectDRBackend() +# @testset "InspectDR" begin +# @fact inspectdr() == Plots.InspectDRBackend() +# @fact backend() == Plots.InspectDRBackend() # # image_comparison_facts(:inspectdr, # skip=[ @@ -72,41 +72,41 @@ end # end -# facts("Plotly") do -# @fact plotly() --> Plots.PlotlyBackend() -# @fact backend() --> Plots.PlotlyBackend() +# @testset "Plotly" begin +# @fact plotly() == Plots.PlotlyBackend() +# @fact backend() == Plots.PlotlyBackend() # # # # until png generation is reliable on OSX, just test on linux # # @static is_linux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps) # end -# facts("Immerse") do -# @fact immerse() --> Plots.ImmerseBackend() -# @fact backend() --> Plots.ImmerseBackend() +# @testset "Immerse" begin +# @fact immerse() == Plots.ImmerseBackend() +# @fact backend() == Plots.ImmerseBackend() # # # as long as we can plot anything without error, it should be the same as Gadfly # image_comparison_facts(:immerse, only=[1], eps=img_eps) # end -# facts("PlotlyJS") do -# @fact plotlyjs() --> Plots.PlotlyJSBackend() -# @fact backend() --> Plots.PlotlyJSBackend() +# @testset "PlotlyJS" begin +# @fact plotlyjs() == Plots.PlotlyJSBackend() +# @fact backend() == Plots.PlotlyJSBackend() # # # as long as we can plot anything without error, it should be the same as Plotly # image_comparison_facts(:plotlyjs, only=[1], eps=img_eps) # end -# facts("Gadfly") do -# @fact gadfly() --> Plots.GadflyBackend() -# @fact backend() --> Plots.GadflyBackend() +# @testset "Gadfly" begin +# @fact gadfly() == Plots.GadflyBackend() +# @fact backend() == Plots.GadflyBackend() # -# @fact typeof(plot(1:10)) --> Plots.Plot{Plots.GadflyBackend} -# @fact plot(Int[1,2,3], rand(3)) --> not(nothing) -# @fact plot(sort(rand(10)), rand(Int, 10, 3)) --> not(nothing) -# @fact plot!(rand(10,3), rand(10,3)) --> not(nothing) +# @fact typeof(plot(1:10)) == Plots.Plot{Plots.GadflyBackend} +# @fact plot(Int[1,2,3], rand(3)) == not(nothing) +# @fact plot(sort(rand(10)), rand(Int, 10, 3)) == not(nothing) +# @fact plot!(rand(10,3), rand(10,3)) == not(nothing) # # image_comparison_facts(:gadfly, skip=[4,6,23,24,27], eps=img_eps) # end @@ -114,24 +114,24 @@ end -facts("Axes") do +@testset "Axes" begin p = plot() axis = p.subplots[1][:xaxis] - @fact typeof(axis) --> Plots.Axis - @fact Plots.discrete_value!(axis, "HI") --> (0.5, 1) - @fact Plots.discrete_value!(axis, :yo) --> (1.5, 2) - @fact Plots.ignorenan_extrema(axis) --> (0.5,1.5) - @fact axis[:discrete_map] --> Dict{Any,Any}(:yo => 2, "HI" => 1) + @fact typeof(axis) == Plots.Axis + @fact Plots.discrete_value!(axis, "HI") == (0.5, 1) + @fact Plots.discrete_value!(axis, :yo) == (1.5, 2) + @fact Plots.ignorenan_extrema(axis) == (0.5,1.5) + @fact axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1) Plots.discrete_value!(axis, ["x$i" for i=1:5]) Plots.discrete_value!(axis, ["x$i" for i=0:2]) - @fact Plots.ignorenan_extrema(axis) --> (0.5, 7.5) + @fact Plots.ignorenan_extrema(axis) == (0.5, 7.5) end # tests for preprocessing recipes -# facts("recipes") do +# @testset "recipes" begin # user recipe @@ -168,6 +168,4 @@ end # end - -FactCheck.exitstatus() end # module From 371406845ca713d458aaff749ada1db15b18f8e2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 13:43:58 +0200 Subject: [PATCH 229/720] drop Glob (enable testing on Windows) --- test/imgcomp.jl | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 1d4d3e05..f600d94c 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -16,7 +16,6 @@ end using Plots using StatPlots using Base.Test -using Glob default(size=(500,300)) @@ -43,11 +42,7 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is fn = "ref$idx.png" # firgure out version info - G = glob(joinpath(relpath(refdir), "*")) - # @show refdir fn G - slash = (@static is_windows() ? "\\" : "/") - versions = map(fn -> VersionNumber(split(fn, slash)[end]), G) - versions = reverse(sort(versions)) + versions = sort(VersionNumber.(readdir(refdir)), rev = true) versions = filter(v -> v <= _current_plots_version, versions) # @show refdir fn versions From 7b15f7d74b1cc57941b437346a8f9bb4c000f713 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 16:08:45 +0200 Subject: [PATCH 230/720] fix round() deprecation in gr.jl --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 989a0751..8ab730f3 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -853,7 +853,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # create the colorbar of contour levels if sp[:colorbar] != :none gr_set_viewport_cmap(sp) - l = round(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) + l = round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) From 82ecf894c0e1623215efe0f4864879aef2d96955 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 21:50:06 +0200 Subject: [PATCH 231/720] fix issues - replace at-fact with at-test --- test/runtests.jl | 60 ++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index ba8666ec..69b4d393 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,34 +8,34 @@ default(show=false, reuse=true) img_eps = isinteractive() ? 1e-2 : 10e-2 @testset "GR" begin - @fact gr() == Plots.GRBackend() - @fact backend() == Plots.GRBackend() + @test gr() == Plots.GRBackend() + @test backend() == Plots.GRBackend() image_comparison_facts(:gr, eps=img_eps) end @testset "PyPlot" begin - @fact pyplot() == Plots.PyPlotBackend() - @fact backend() == Plots.PyPlotBackend() + @test pyplot() == Plots.PyPlotBackend() + @test backend() == Plots.PyPlotBackend() image_comparison_facts(:pyplot, eps=img_eps) end @testset "UnicodePlots" begin - @fact unicodeplots() == Plots.UnicodePlotsBackend() - @fact backend() == Plots.UnicodePlotsBackend() + @test unicodeplots() == Plots.UnicodePlotsBackend() + @test backend() == Plots.UnicodePlotsBackend() # lets just make sure it runs without error - @fact isa(plot(rand(10)), Plots.Plot) == true + @test isa(plot(rand(10)), Plots.Plot) == true end # The plotlyjs testimages return a connection error on travis: # connect: connection refused (ECONNREFUSED) -@testset "PlotlyJS" begin -# @fact plotlyjs() == Plots.PlotlyJSBackend() -# @fact backend() == Plots.PlotlyJSBackend() +# @testset "PlotlyJS" begin +# @test plotlyjs() == Plots.PlotlyJSBackend() +# @test backend() == Plots.PlotlyJSBackend() # # if is_linux() && isinteractive() # image_comparison_facts(:plotlyjs, @@ -54,8 +54,8 @@ end # in Gtk.GLib.GError(::Gtk.##229#230) at /home/travis/.julia/v0.5/Gtk/src/GLib/gerror.jl:17 # @testset "InspectDR" begin -# @fact inspectdr() == Plots.InspectDRBackend() -# @fact backend() == Plots.InspectDRBackend() +# @test inspectdr() == Plots.InspectDRBackend() +# @test backend() == Plots.InspectDRBackend() # # image_comparison_facts(:inspectdr, # skip=[ @@ -73,8 +73,8 @@ end # @testset "Plotly" begin -# @fact plotly() == Plots.PlotlyBackend() -# @fact backend() == Plots.PlotlyBackend() +# @test plotly() == Plots.PlotlyBackend() +# @test backend() == Plots.PlotlyBackend() # # # # until png generation is reliable on OSX, just test on linux # # @static is_linux() && image_comparison_facts(:plotly, only=[1,3,4,7,8,9,10,11,12,14,15,20,22,23,27], eps=img_eps) @@ -82,8 +82,8 @@ end # @testset "Immerse" begin -# @fact immerse() == Plots.ImmerseBackend() -# @fact backend() == Plots.ImmerseBackend() +# @test immerse() == Plots.ImmerseBackend() +# @test backend() == Plots.ImmerseBackend() # # # as long as we can plot anything without error, it should be the same as Gadfly # image_comparison_facts(:immerse, only=[1], eps=img_eps) @@ -91,8 +91,8 @@ end # @testset "PlotlyJS" begin -# @fact plotlyjs() == Plots.PlotlyJSBackend() -# @fact backend() == Plots.PlotlyJSBackend() +# @test plotlyjs() == Plots.PlotlyJSBackend() +# @test backend() == Plots.PlotlyJSBackend() # # # as long as we can plot anything without error, it should be the same as Plotly # image_comparison_facts(:plotlyjs, only=[1], eps=img_eps) @@ -100,13 +100,13 @@ end # @testset "Gadfly" begin -# @fact gadfly() == Plots.GadflyBackend() -# @fact backend() == Plots.GadflyBackend() +# @test gadfly() == Plots.GadflyBackend() +# @test backend() == Plots.GadflyBackend() # -# @fact typeof(plot(1:10)) == Plots.Plot{Plots.GadflyBackend} -# @fact plot(Int[1,2,3], rand(3)) == not(nothing) -# @fact plot(sort(rand(10)), rand(Int, 10, 3)) == not(nothing) -# @fact plot!(rand(10,3), rand(10,3)) == not(nothing) +# @test typeof(plot(1:10)) == Plots.Plot{Plots.GadflyBackend} +# @test plot(Int[1,2,3], rand(3)) == not(nothing) +# @test plot(sort(rand(10)), rand(Int, 10, 3)) == not(nothing) +# @test plot!(rand(10,3), rand(10,3)) == not(nothing) # # image_comparison_facts(:gadfly, skip=[4,6,23,24,27], eps=img_eps) # end @@ -117,15 +117,15 @@ end @testset "Axes" begin p = plot() axis = p.subplots[1][:xaxis] - @fact typeof(axis) == Plots.Axis - @fact Plots.discrete_value!(axis, "HI") == (0.5, 1) - @fact Plots.discrete_value!(axis, :yo) == (1.5, 2) - @fact Plots.ignorenan_extrema(axis) == (0.5,1.5) - @fact axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1) + @test typeof(axis) == Plots.Axis + @test Plots.discrete_value!(axis, "HI") == (0.5, 1) + @test Plots.discrete_value!(axis, :yo) == (1.5, 2) + @test Plots.ignorenan_extrema(axis) == (0.5,1.5) + @test axis[:discrete_map] == Dict{Any,Any}(:yo => 2, "HI" => 1) Plots.discrete_value!(axis, ["x$i" for i=1:5]) Plots.discrete_value!(axis, ["x$i" for i=0:2]) - @fact Plots.ignorenan_extrema(axis) == (0.5, 7.5) + @test Plots.ignorenan_extrema(axis) == (0.5, 7.5) end From da7e57989c2f3727cb16a213fea7a02b918a3aea Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 22:55:05 +0200 Subject: [PATCH 232/720] drop FactCheck and Glob in test/REQUIRE --- test/REQUIRE | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/REQUIRE b/test/REQUIRE index 57bc7828..e748b0c5 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -1,5 +1,4 @@ StatPlots -FactCheck Images ImageMagick @osx QuartzImageIO @@ -7,4 +6,3 @@ GR RDatasets VisualRegressionTests UnicodePlots -Glob From 52f042263b21acc27774d94da841bb7fbc5b51a6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 20 Jul 2017 23:38:16 +0200 Subject: [PATCH 233/720] fix case --- src/backends/gr.jl | 2 +- src/utils.jl | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index a79cf62f..6168a1de 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1049,7 +1049,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) should_add_to_legend(series) || continue st = series[:seriestype] gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - if st == :path && (series[:fillrange] == nothing || has_ribbon(series)) + if st == :path && (series[:fillrange] == nothing || series[:ribbon] != nothing) GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) elseif st == :shape || series[:fillrange] != nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) diff --git a/src/utils.jl b/src/utils.jl index 84d82ea5..d8aced3d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -497,12 +497,6 @@ function make_fillrange_from_ribbon(kw::KW) kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2) end -# check if series has a ribbon -function has_ribbon(series::Series) - series[:ribbon] == nothing && return false - return series[:ribbon] > 0 -end - function get_sp_lims(sp::Subplot, letter::Symbol) axis_limits(sp[Symbol(letter, :axis)]) end From 1ff8663e447eabfdd309eb655bc8ca5537766391 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 21 Jul 2017 01:12:39 +0200 Subject: [PATCH 234/720] allow setting surface alpha in plotly --- src/backends/plotly.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 440884a9..9f764f4c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -508,6 +508,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:showscale] = false else d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) + d_out[:opacity] = series[:fillalpha] if series[:fill_z] != nothing d_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z]) end From 9f712b44f34fce4efa927f7d1439e3b93fc114db Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 21 Jul 2017 09:12:27 +0200 Subject: [PATCH 235/720] add ribbon area to marker --- src/backends/gr.jl | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6168a1de..acb06b04 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1049,16 +1049,19 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) should_add_to_legend(series) || continue st = series[:seriestype] gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - if st == :path && (series[:fillrange] == nothing || series[:ribbon] != nothing) - GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) - elseif st == :shape || series[:fillrange] != nothing + + if st == :shape || series[:fillrange] != nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) l, r = xpos-0.07, xpos-0.01 b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] y = [b, b, t, t, b] gr_polyline(x, y, GR.fillarea) - gr_polyline(x, y) + series[:ribbon] != nothing || gr_polyline(x, y) + end + + if st == :path && (series[:fillrange] == nothing || series[:ribbon] != nothing) + GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) end if series[:markershape] != :none From 96d34bb5eeaf82a9ec20c08d6930e64374b0cdda Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 21 Jul 2017 10:05:27 +0200 Subject: [PATCH 236/720] changed marker for path with fillrange --- src/backends/gr.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index acb06b04..a3a40caf 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1057,11 +1057,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) x = [l, r, r, l, l] y = [b, b, t, t, b] gr_polyline(x, y, GR.fillarea) - series[:ribbon] != nothing || gr_polyline(x, y) + st == :shape && gr_polyline(x, y) end - if st == :path && (series[:fillrange] == nothing || series[:ribbon] != nothing) - GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) + if st == :path + if series[:fillrange] == nothing || series[:ribbon] != nothing + GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) + else + GR.polyline([xpos - 0.07, xpos - 0.01], [ypos+0.4dy, ypos+0.4dy]) + end end if series[:markershape] != :none From 0fa459d590a38c4529bd1d17346ed9b36a3f97e1 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 21 Jul 2017 10:52:36 +0200 Subject: [PATCH 237/720] fix alpha in legend markers --- src/backends/gr.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index a3a40caf..4c36bf00 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -272,6 +272,10 @@ function normalize_zvals(zv::AVec) end end + +gr_alpha(α::Void) = 1 +gr_alpha(α::Real) = α + # --------------------------------------------------------- # draw ONE Shape @@ -1042,6 +1046,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if sp[:legendtitle] != nothing GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) gr_set_textcolor(sp[:foreground_color_legend]) + GR.settransparency(1) gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) ypos -= dy end @@ -1056,11 +1061,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] y = [b, b, t, t, b] + GR.settransparency(gr_alpha(series[:fillalpha])) gr_polyline(x, y, GR.fillarea) + GR.settransparency(gr_alpha(series[:linealpha])) st == :shape && gr_polyline(x, y) end if st == :path + GR.settransparency(gr_alpha(series[:linealpha])) if series[:fillrange] == nothing || series[:ribbon] != nothing GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) else From 44b533f50165db6d28eb3f62f25a53fdf4cbb997 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 24 Jul 2017 10:02:44 +0200 Subject: [PATCH 238/720] allow matplotlib 1.5 usage --- src/backends/pyplot.jl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 9f5e8a24..964fb049 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -83,6 +83,14 @@ function _initialize_backend(::PyPlotBackend) const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections")) const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d")) + # "support" matplotlib v1.5 + const set_facecolor_sym = if PyPlot.version < v"2" + warning("You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0") + :set_axis_bgcolor + else + :set_facecolor + end + # we don't want every command to update the figure PyPlot.ioff() end @@ -985,7 +993,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) fig[:clear]() dpi = plt[:dpi] fig[:set_size_inches](w/dpi, h/dpi, forward = true) - fig[:set_facecolor](py_color(plt[:background_color_outside])) + fig[set_facecolor_sym](py_color(plt[:background_color_outside])) fig[:set_dpi](dpi) # resize the window @@ -1074,7 +1082,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) py_add_legend(plt, sp, ax) # this sets the bg color inside the grid - ax[:set_facecolor](py_color(sp[:background_color_inside])) + ax[set_facecolor_sym](py_color(sp[:background_color_inside])) end py_drawfig(fig) end @@ -1196,7 +1204,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # set some legend properties frame = leg[:get_frame]() - frame[:set_facecolor](py_color(sp[:background_color_legend])) + frame[set_facecolor_sym](py_color(sp[:background_color_legend])) frame[:set_edgecolor](fgcolor) end end From 6ecd30d42b810b4048e6effa13627e675bf9c150 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 24 Jul 2017 14:55:28 +0200 Subject: [PATCH 239/720] warning --> warn --- 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 964fb049..aaa0effa 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -85,7 +85,7 @@ function _initialize_backend(::PyPlotBackend) # "support" matplotlib v1.5 const set_facecolor_sym = if PyPlot.version < v"2" - warning("You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0") + warn("You are using Matplotlib $(PyPlot.version), which is no longer officialy supported by the Plots community. To ensure smooth Plots.jl integration update your Matplotlib library to a version >= 2.0.0") :set_axis_bgcolor else :set_facecolor From 00e05efd7c0b713088dc4a2d62125daebab140d2 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 26 Jul 2017 08:25:58 +0200 Subject: [PATCH 240/720] gr: fixed padding for guides --- src/backends/gr.jl | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 60013086..46135842 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -538,7 +538,20 @@ end function _update_min_padding!(sp::Subplot{GRBackend}) - sp.minpad = (10mm,2mm,2mm,8mm) + leftpad = 10mm + toppad = 2mm + rightpad = 2mm + bottompad = 6mm + if sp[:title] != "" + toppad += 5mm + end + if sp[:xaxis][:guide] != "" + bottompad += 4mm + end + if sp[:yaxis][:guide] != "" + leftpad += 4mm + end + sp.minpad = (leftpad, toppad, rightpad, bottompad) end From 8d9ff7af11f512ba9dd575cbc4999f0ac61342c5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 26 Jul 2017 14:50:57 +0200 Subject: [PATCH 241/720] prepare v0.12.1 release --- NEWS.md | 16 +++++++++++++++- src/Plots.jl | 2 +- test/imgcomp.jl | 2 +- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 2637f9bb..dd5f37b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,8 +9,22 @@ - `backports` branch is for Julia 0.4 --- +## 0.12.1 (current master/dev) -## 0.12 (current master/dev) +- fix deprecation warnings +- switch from FixedSizeArrays to StaticArrays.FixedSizeArrays +- drop FactCheck in tests +- remove julia 0.5 compliant uses of transpose operator +- fix GR heatmap bugs +- fix GR guide padding +- improve legend markers in GR +- add surface alpha for Plotly(JS) +- add fillrange to Plotly(JS) +- allow usage of Matplotlib 1.5 with PyPlot +- fix GLVisualize for julia 0.6 +- conform to changes in InspectDR + +#### 0.12.0 - 0.6 only diff --git a/src/Plots.jl b/src/Plots.jl index 993fb246..0d7dffa7 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots diff --git a/test/imgcomp.jl b/test/imgcomp.jl index cd3b7058..2c02003c 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -24,7 +24,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.12.0" +const _current_plots_version = v"0.12.1" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From dabc3f998b66e4b7e4bfc577f188fd58b10c46ae Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 26 Jul 2017 15:14:07 +0200 Subject: [PATCH 242/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 7b61df07..3b87b433 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 2c191dbdbfc6adff907be26931c789b8bb26eeac Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Wed, 26 Jul 2017 16:34:03 -0400 Subject: [PATCH 243/720] don't use pywrap (closes #983) --- src/backends/pyplot.jl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 3372da4d..42befe5a 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -70,18 +70,18 @@ function _initialize_backend(::PyPlotBackend) append!(Base.Multimedia.displays, otherdisplays) export PyPlot - const pycolors = PyPlot.pywrap(PyPlot.pyimport("matplotlib.colors")) - const pypath = PyPlot.pywrap(PyPlot.pyimport("matplotlib.path")) - const mplot3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d")) - const pypatches = PyPlot.pywrap(PyPlot.pyimport("matplotlib.patches")) - const pyfont = PyPlot.pywrap(PyPlot.pyimport("matplotlib.font_manager")) - const pyticker = PyPlot.pywrap(PyPlot.pyimport("matplotlib.ticker")) - const pycmap = PyPlot.pywrap(PyPlot.pyimport("matplotlib.cm")) - const pynp = PyPlot.pywrap(PyPlot.pyimport("numpy")) - pynp.seterr(invalid="ignore") - const pytransforms = PyPlot.pywrap(PyPlot.pyimport("matplotlib.transforms")) - const pycollections = PyPlot.pywrap(PyPlot.pyimport("matplotlib.collections")) - const pyart3d = PyPlot.pywrap(PyPlot.pyimport("mpl_toolkits.mplot3d.art3d")) + const pycolors = PyPlot.pyimport("matplotlib.colors") + const pypath = PyPlot.pyimport("matplotlib.path") + const mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d") + const pypatches = PyPlot.pyimport("matplotlib.patches") + const pyfont = PyPlot.pyimport("matplotlib.font_manager") + const pyticker = PyPlot.pyimport("matplotlib.ticker") + const pycmap = PyPlot.pyimport("matplotlib.cm") + const pynp = PyPlot.pyimport("numpy") + pynp["seterr"](invalid="ignore") + const pytransforms = PyPlot.pyimport("matplotlib.transforms") + const pycollections = PyPlot.pyimport("matplotlib.collections") + const pyart3d = PyPlot.pyimport("mpl_toolkits.mplot3d.art3d") # we don't want every command to update the figure PyPlot.ioff() @@ -118,7 +118,7 @@ py_color(grad::ColorGradient) = py_color(grad.colors) function py_colormap(grad::ColorGradient) pyvals = [(z, py_color(grad[z])) for z in grad.values] - cm = pycolors.LinearSegmentedColormap[:from_list]("tmp", pyvals) + cm = pycolors["LinearSegmentedColormap"][:from_list]("tmp", pyvals) cm[:set_bad](color=(0,0,0,0.0), alpha=0.0) cm end @@ -256,7 +256,7 @@ function labelfunc(scale::Symbol, backend::PyPlotBackend) end function py_mask_nans(z) - # PyPlot.pywrap(pynp.ma[:masked_invalid](PyPlot.pywrap(z))) + # pynp.ma[:masked_invalid](z))) PyCall.pycall(pynp.ma[:masked_invalid], Any, z) # pynp.ma[:masked_where](pynp.isnan(z),z) end From 780f3c49e9dc98e8a8d510acc4189063d673dd95 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 27 Jul 2017 16:37:55 +0200 Subject: [PATCH 244/720] Add test for markershape --- src/args.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/args.jl b/src/args.jl index b3baa777..ea4f8627 100644 --- a/src/args.jl +++ b/src/args.jl @@ -706,6 +706,9 @@ function preprocessArgs!(d::KW) delete!(d, :marker) if haskey(d, :markershape) d[:markershape] = _replace_markershape(d[:markershape]) + if d[:markershape] == :none && d[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) #the default should be :auto, not :none, so that :none can be set explicitly and would be respected + d[:markershape] = :circle + end elseif anymarker d[:markershape_to_add] = :circle # add it after _apply_recipe end From d0070c72fdefd3298c9230587b17d33f5555ee44 Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Thu, 27 Jul 2017 14:15:48 -0400 Subject: [PATCH 245/720] whoops, forgot to commit these pywrap fixes --- src/backends/pyplot.jl | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 42befe5a..d0572e5d 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -101,7 +101,7 @@ end # function py_colormap(c::ColorGradient, α=nothing) # pyvals = [(v, py_color(getColorZ(c, v), α)) for v in c.values] -# pycolors.pymember("LinearSegmentedColormap")[:from_list]("tmp", pyvals) +# pycolors["LinearSegmentedColormap"][:from_list]("tmp", pyvals) # end # # convert vectors and ColorVectors to standard ColorGradients @@ -127,7 +127,7 @@ py_colormap(c) = py_colormap(cgrad()) function py_shading(c, z) cmap = py_colormap(c) - ls = pycolors.pymember("LightSource")(270,45) + ls = pycolors["LightSource"](270,45) ls[:shade](z, cmap, vert_exag=0.1, blend_mode="soft") end @@ -151,7 +151,7 @@ function py_marker(marker::Shape) mat[i,2] = y[i] end mat[n+1,:] = mat[1,:] - pypath.pymember("Path")(mat) + pypath["Path"](mat) end const _path_MOVETO = UInt8(1) @@ -177,7 +177,7 @@ const _path_CLOSEPOLY = UInt8(79) # lastnan = nan # end # codes[n+1] = _path_CLOSEPOLY -# pypath.pymember("Path")(mat, codes) +# pypath["Path"](mat, codes) # end # get the marker shape @@ -227,14 +227,14 @@ end # # untested... return a FontProperties object from a Plots.Font # function py_font(font::Font) -# pyfont.pymember("FontProperties")( +# pyfont["FontProperties"]( # family = font.family, # size = font.size # ) # end function get_locator_and_formatter(vals::AVec) - pyticker.pymember("FixedLocator")(1:length(vals)), pyticker.pymember("FixedFormatter")(vals) + pyticker["FixedLocator"](1:length(vals)), pyticker["FixedFormatter"](vals) end function add_pyfixedformatter(cbar, vals::AVec) @@ -256,9 +256,9 @@ function labelfunc(scale::Symbol, backend::PyPlotBackend) end function py_mask_nans(z) - # pynp.ma[:masked_invalid](z))) - PyCall.pycall(pynp.ma[:masked_invalid], Any, z) - # pynp.ma[:masked_where](pynp.isnan(z),z) + # pynp["ma"][:masked_invalid](z))) + PyCall.pycall(pynp["ma"][:masked_invalid], Any, z) + # pynp["ma"][:masked_where](pynp["isnan"](z),z) end # --------------------------------------------------------------------------- @@ -489,7 +489,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) extrakw = KW() isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - kw[:norm] = pycolors.Normalize(; extrakw...) + kw[:norm] = pycolors["Normalize"](; extrakw...) end lz = collect(series[:line_z]) handle = if is3d(st) @@ -500,7 +500,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # for i=1:n # segments[i] = [(_cycle(x,i), _cycle(y,i), _cycle(z,i)), (_cycle(x,i+1), _cycle(y,i+1), _cycle(z,i+1))] # end - lc = pyart3d.Line3DCollection(segments; kw...) + lc = pyart3d["Line3DCollection"](segments; kw...) lc[:set_array](lz) ax[:add_collection3d](lc, zs=z) #, zdir='y') lc @@ -512,7 +512,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # for i=1:n # segments[i] = [(_cycle(x,i), _cycle(y,i)), (_cycle(x,i+1), _cycle(y,i+1))] # end - lc = pycollections.LineCollection(segments; kw...) + lc = pycollections["LineCollection"](segments; kw...) lc[:set_array](lz) ax[:add_collection](lc) lc @@ -797,8 +797,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = [] for (i,rng) in enumerate(iter_segments(x, y)) if length(rng) > 1 - path = pypath.pymember("Path")(hcat(x[rng], y[rng])) - patches = pypatches.pymember("PathPatch")( + path = pypath["Path"](hcat(x[rng], y[rng])) + patches = pypatches["PathPatch"]( path; label = series[:label], zorder = series[:series_plotindex], From 26a56c3105c7f45f4b8ca7f1be125895cce368d1 Mon Sep 17 00:00:00 2001 From: john verzani Date: Thu, 27 Jul 2017 15:48:52 -0400 Subject: [PATCH 246/720] Update appveyor.yml add testing on v0.6 with 32 and 64 bit. --- appveyor.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index c0464e36..5a846a42 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,6 +2,8 @@ environment: matrix: - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" From 8c3c07acb7c14b5c942ad966485a01ccae4b046c Mon Sep 17 00:00:00 2001 From: john verzani Date: Thu, 27 Jul 2017 16:56:17 -0400 Subject: [PATCH 247/720] Update appveyor.yml remove v0.5 testing from appveyor --- appveyor.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 5a846a42..cc07d84a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,7 +1,5 @@ environment: matrix: - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.5/julia-0.5-latest-win32.exe" - - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.5/julia-0.5-latest-win64.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" From 50ec31a7a3ea206d6617555ac0b9e3f2e05850dd Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 28 Jul 2017 12:17:47 +0200 Subject: [PATCH 248/720] gr: improved calculation of bottom margin --- src/backends/gr.jl | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 46135842..7525926a 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -357,7 +357,7 @@ function gr_set_fill(c) #, a) end # this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses) -const _gr_point_mult = zeros(1) +const _gr_point_mult = 0.0018 * ones(1) # set the font attributes... assumes _gr_point_mult has been populated already function gr_set_font(f::Font; halign = f.halign, valign = f.valign, @@ -388,7 +388,7 @@ end const viewport_plotarea = zeros(4) # the size of the current plot in pixels -const gr_plot_size = zeros(2) +const gr_plot_size = [600.0, 400.0] function gr_viewport_from_bbox(sp::Subplot{GRBackend}, bb::BoundingBox, w, h, viewport_canvas) viewport = zeros(4) @@ -546,7 +546,22 @@ function _update_min_padding!(sp::Subplot{GRBackend}) toppad += 5mm end if sp[:xaxis][:guide] != "" - bottompad += 4mm + xticks = axis_drawing_info(sp)[1] + if !(xticks in (nothing, false)) + gr_set_font(sp[:xaxis][:tickfont], + halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], + valign = :top, + color = sp[:xaxis][:foreground_color_axis], + rotation = sp[:xaxis][:rotation]) + h = 0 + for (cv, dv) in zip(xticks...) + tbx, tby = gr_inqtext(0, 0, string(dv)) + h = max(h, tby[2] - tby[1]) + end + bottompad += 1mm + gr_plot_size[2] * h * px + else + bottompad += 4mm + end end if sp[:yaxis][:guide] != "" leftpad += 4mm From 9f0117d914c3a558a08b800a7fd58f2fd64f87c1 Mon Sep 17 00:00:00 2001 From: john verzani Date: Tue, 1 Aug 2017 15:48:12 -0400 Subject: [PATCH 249/720] Update README.md add appveyor badge. (But how does appveyor get run, as it doesn't seem to be current) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b88fe561..72a82007 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Plots [![Build Status](https://travis-ci.org/JuliaPlots/Plots.jl.svg?branch=master)](https://travis-ci.org/JuliaPlots/Plots.jl) +[![Build status](https://ci.appveyor.com/api/projects/status/github/tbreloff/plots.jl?branch=master&svg=true)](https://ci.appveyor.com/project/tbreloff/plots-jl) [![Join the chat at https://gitter.im/tbreloff/Plots.jl](https://badges.gitter.im/tbreloff/Plots.jl.svg)](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 2e3bc15d2b3e04ea0fbe386409bf7258e138f99a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 8 Aug 2017 20:24:17 +0200 Subject: [PATCH 250/720] Move when output is included --- src/Plots.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 3b87b433..e7c7fc66 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -151,12 +151,11 @@ include("layouts.jl") include("subplots.jl") include("recipes.jl") include("animation.jl") -include("output.jl") include("examples.jl") include("arg_desc.jl") include("plotattr.jl") include("backends.jl") - +include("output.jl") # --------------------------------------------------------- From 1f07be6ae00e4da6fa2d407a46a99c4fe1b373bc Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 9 Aug 2017 08:05:21 +0200 Subject: [PATCH 251/720] disable precompilation for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index e7c7fc66..625dba5e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 92672ffddfef671812377cd7bab89c20a899b897 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 9 Aug 2017 08:10:04 +0200 Subject: [PATCH 252/720] Update news.md --- NEWS.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index dd5f37b1..8113ae7b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,16 @@ - `backports` branch is for Julia 0.4 --- -## 0.12.1 (current master/dev) +## (current master) + +## 0.12.2 + +- fix an issue with Juno/PlotlyJS compatibility on new installations +- fix markers not showing up in seriesrecipes using :scatter +- don't use pywrap in the pyplot backend +- improve the bottom margin for the gr backend + +## 0.12.1 - fix deprecation warnings - switch from FixedSizeArrays to StaticArrays.FixedSizeArrays From 88d1735380cd0c2f9d358b74732db5f592f45897 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 9 Aug 2017 08:12:22 +0200 Subject: [PATCH 253/720] allow precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 625dba5e..e7c7fc66 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From a937fa0ef8fe38aed81f038181e4303de56bcf25 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 9 Aug 2017 10:46:23 +0200 Subject: [PATCH 254/720] gr: no longer handle '_' and '^' in text --- src/backends/gr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 7525926a..5246d452 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -179,7 +179,7 @@ gr_inqtext(x, y, s::Symbol) = gr_inqtext(x, y, string(s)) function gr_inqtext(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.inqtextext(x, y, s[2:end-1]) - elseif search(s, '\\') != 0 || search(s, '_') != 0 || search(s, '^') != 0 + elseif search(s, '\\') != 0 GR.inqtextext(x, y, s) else GR.inqtext(x, y, s) @@ -191,7 +191,7 @@ gr_text(x, y, s::Symbol) = gr_text(x, y, string(s)) function gr_text(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.mathtex(x, y, s[2:end-1]) - elseif search(s, '\\') != 0 || search(s, '_') != 0 || search(s, '^') != 0 + elseif search(s, '\\') != 0 GR.textext(x, y, s) else GR.text(x, y, s) From d90b2e6142d9b9845e8ef863576525ef94539bce Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 10 Aug 2017 09:08:27 +0200 Subject: [PATCH 255/720] gr: use correct gradient labels for scatter plot --- src/backends/gr.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 5246d452..80b52822 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -860,6 +860,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if series[:markershape] != :none + if series[:marker_z] != nothing + zmin, zmax = extrema(series[:marker_z]) + GR.setspace(zmin, zmax, 0, 90) + GR.setscale(0) + end gr_draw_markers(series, x, y) end From 6b814b8dcadd2e4c9229a951f2d27e42f26a2ee7 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 10 Aug 2017 16:32:24 +0200 Subject: [PATCH 256/720] initial commit mostly a copy of #695 --- src/Plots.jl | 6 ++++++ src/arg_desc.jl | 2 +- src/args.jl | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index e7c7fc66..d320df7c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -52,6 +52,8 @@ export yflip!, xaxis!, yaxis!, + xgrid!, + ygrid!, xlims, ylims, @@ -213,6 +215,8 @@ xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...) xaxis!(args...; kw...) = plot!(; xaxis = args, kw...) yaxis!(args...; kw...) = plot!(; yaxis = args, kw...) +xgrid!(grid::Bool = true; kw...) = plot!(; xgrid = grid, kw...) +ygrid!(grid::Bool = true; kw...) = plot!(; ygrid = grid, kw...) let PlotOrSubplot = Union{Plot, Subplot} title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...) @@ -230,6 +234,8 @@ let PlotOrSubplot = Union{Plot, Subplot} ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; xticks = (ticks,labels), kw...) yticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot, ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; yticks = (ticks,labels), kw...) + xgrid!(plt::PlotOrSubplot, grid::Bool = true; kw...) = plot!(plt; xgrid = grid, kw...) + ygrid!(plt::PlotOrSubplot, grid::Bool = true; kw...) = plot!(plt; ygrid = grid, kw...) annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...) annotate!{T<:Tuple}(plt::PlotOrSubplot, anns::AVec{T}; kw...) = plot!(plt; annotation = anns, kw...) xflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; xflip = flip, kw...) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f244ff99..571400a7 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -84,7 +84,6 @@ const _arg_desc = KW( :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", -:grid => "Bool. Show the grid lines?", :annotations => "(x,y,text) tuple(s). Can be a single tuple or a list of them. Text can be String or PlotText (created with `text(args...)`) Add one-off text annotations at the x,y coordinates.", :projection => "Symbol or String. '3d' or 'polar'", :aspect_ratio => "Symbol (:equal) or Number. Plot area is resized so that 1 y-unit is the same size as `apect_ratio` x-units.", @@ -111,5 +110,6 @@ const _arg_desc = KW( :foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.", :foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).", :mirror => "Bool. Switch the side of the tick labels (right or top).", +:grid => "Bool. Show the grid lines?", ) diff --git a/src/args.jl b/src/args.jl index ea4f8627..cf023191 100644 --- a/src/args.jl +++ b/src/args.jl @@ -247,7 +247,6 @@ const _subplot_defaults = KW( :background_color_inside => :match, # background inside grid :foreground_color_subplot => :match, # default for other fg colors... match takes plot default :foreground_color_legend => :match, # foreground of legend - :foreground_color_grid => :match, # grid color :foreground_color_title => :match, # title color :color_palette => :auto, :legend => :best, @@ -255,7 +254,6 @@ const _subplot_defaults = KW( :colorbar => :legend, :clims => :auto, :legendfont => font(8), - :grid => true, :annotations => [], # annotation tuples... list of (x,y,annotation) :projection => :none, # can also be :polar or :3d :aspect_ratio => :none, # choose from :none or :equal @@ -285,6 +283,8 @@ const _axis_defaults = KW( :discrete_values => [], :formatter => :auto, :mirror => false, + :grid => true, + :foreground_color_grid => :match, # grid color ) const _suppress_warnings = Set{Symbol}([ From c60d66d94a3873748b8e70f15333209766a60463 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 10 Aug 2017 17:46:11 +0200 Subject: [PATCH 257/720] make it work for gr, pyplot and plotly(js) --- src/args.jl | 4 +-- src/axes.jl | 58 +++++++++++++++++++++++++----------------- src/backends/gr.jl | 28 ++++++++++++-------- src/backends/plotly.jl | 7 ++--- src/backends/pyplot.jl | 4 +-- 5 files changed, 61 insertions(+), 40 deletions(-) diff --git a/src/args.jl b/src/args.jl index cf023191..0012bc7e 100644 --- a/src/args.jl +++ b/src/args.jl @@ -943,7 +943,6 @@ const _match_map = KW( :background_color_legend => :background_color_subplot, :background_color_inside => :background_color_subplot, :foreground_color_legend => :foreground_color_subplot, - :foreground_color_grid => :foreground_color_subplot, :foreground_color_title => :foreground_color_subplot, :left_margin => :margin, :top_margin => :margin, @@ -957,6 +956,7 @@ const _match_map2 = KW( :foreground_color_subplot => :foreground_color, :foreground_color_axis => :foreground_color_subplot, :foreground_color_border => :foreground_color_subplot, + :foreground_color_grid => :foreground_color_subplot, :foreground_color_guide => :foreground_color_subplot, :foreground_color_text => :foreground_color_subplot, ) @@ -1091,7 +1091,6 @@ function _update_subplot_colors(sp::Subplot) # foreground colors color_or_nothing!(sp.attr, :foreground_color_subplot) color_or_nothing!(sp.attr, :foreground_color_legend) - color_or_nothing!(sp.attr, :foreground_color_grid) color_or_nothing!(sp.attr, :foreground_color_title) return end @@ -1143,6 +1142,7 @@ function _update_axis_colors(axis::Axis) color_or_nothing!(axis.d, :foreground_color_border) color_or_nothing!(axis.d, :foreground_color_guide) color_or_nothing!(axis.d, :foreground_color_text) + color_or_nothing!(axis.d, :foreground_color_grid) return end diff --git a/src/axes.jl b/src/axes.jl index e53d3ccb..6ac60b7c 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -490,38 +490,50 @@ function axis_drawing_info(sp::Subplot) ymin, ymax = axis_limits(yaxis) xticks = get_ticks(xaxis) yticks = get_ticks(yaxis) - spine_segs = Segments(2) - grid_segs = Segments(2) + xspine_segs = Segments(2) + yspine_segs = Segments(2) + xgrid_segs = Segments(2) + ygrid_segs = Segments(2) + + f = scalefunc(yaxis[:scale]) + invf = invscalefunc(yaxis[:scale]) + t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) + t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) if !(xaxis[:ticks] in (nothing, false)) - f = scalefunc(yaxis[:scale]) - invf = invscalefunc(yaxis[:scale]) - t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) - t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - - push!(spine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine - # push!(spine_segs, (xmin,ymax), (xmax,ymax)) # top spine + push!(xspine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine + # push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine for xtick in xticks[1] - push!(spine_segs, (xtick, ymin), (xtick, t1)) # bottom tick - push!(grid_segs, (xtick, t1), (xtick, t2)) # vertical grid - # push!(spine_segs, (xtick, ymax), (xtick, t2)) # top tick + push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick + # push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick end end + if !(xaxis[:grid] in (nothing, false)) + for xtick in xticks[1] + push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + end + end + + f = scalefunc(xaxis[:scale]) + invf = invscalefunc(xaxis[:scale]) + t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) + t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) + if !(yaxis[:ticks] in (nothing, false)) - f = scalefunc(xaxis[:scale]) - invf = invscalefunc(xaxis[:scale]) - t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) - t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - - push!(spine_segs, (xmin,ymin), (xmin,ymax)) # left spine - # push!(spine_segs, (xmax,ymin), (xmax,ymax)) # right spine + push!(yspine_segs, (xmin,ymin), (xmin,ymax)) # left spine + # push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine for ytick in yticks[1] - push!(spine_segs, (xmin, ytick), (t1, ytick)) # left tick - push!(grid_segs, (t1, ytick), (t2, ytick)) # horizontal grid - # push!(spine_segs, (xmax, ytick), (t2, ytick)) # right tick + push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick + # push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick end end - xticks, yticks, spine_segs, grid_segs + if !(yaxis[:grid] in (nothing, false)) + for ytick in yticks[1] + push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + end + end + + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 80b52822..e2e42a26 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -691,10 +691,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1]) # GR.setlinetype(GR.LINETYPE_DOTTED) - if sp[:grid] - GR.grid3d(xtick, 0, ztick, xmin, ymax, zmin, 2, 0, 2) - GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) - end + # if sp[:grid] + GR.grid3d(xtick, 0, ztick, xmin, ymax, zmin, 2, 0, 2) + GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) + # end GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) @@ -709,23 +709,31 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setwindow(xmin, xmax, ymin, ymax) end - xticks, yticks, spine_segs, grid_segs = axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = axis_drawing_info(sp) # @show xticks yticks #spine_segs grid_segs # draw the grid lines - if sp[:grid] + if !(xaxis[:grid] in (nothing, false)) # gr_set_linecolor(sp[:foreground_color_grid]) # GR.grid(xtick, ytick, 0, 0, majorx, majory) - gr_set_line(1, :dot, sp[:foreground_color_grid]) + gr_set_line(1, :dot, xaxis[:foreground_color_grid]) GR.settransparency(0.5) - gr_polyline(coords(grid_segs)...) + gr_polyline(coords(xgrid_segs)...) + end + if !(yaxis[:grid] in (nothing, false)) + gr_set_line(1, :dot, yaxis[:foreground_color_grid]) + GR.settransparency(0.5) + gr_polyline(coords(ygrid_segs)...) end GR.settransparency(1.0) # spine (border) and tick marks - gr_set_line(1, :solid, sp[:xaxis][:foreground_color_axis]) + gr_set_line(1, :solid, xaxis[:foreground_color_axis]) GR.setclip(0) - gr_polyline(coords(spine_segs)...) + gr_polyline(coords(xspine_segs)...) + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + GR.setclip(0) + gr_polyline(coords(yspine_segs)...) GR.setclip(1) if !(xticks in (nothing, false)) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9f764f4c..0a1e25aa 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -5,7 +5,8 @@ const _plotly_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_guide, - # :foreground_color_grid, :foreground_color_axis, + :foreground_color_grid, + # :foreground_color_axis, :foreground_color_text, :foreground_color_border, :foreground_color_title, :label, @@ -213,7 +214,7 @@ function plotly_axis(axis::Axis, sp::Subplot) letter = axis[:letter] ax = KW( :title => axis[:guide], - :showgrid => sp[:grid], + :showgrid => !(axis[:grid] in (nothing, false)), :zeroline => false, :ticks => "inside", ) @@ -230,7 +231,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) ax[:tickcolor] = rgba_string(axis[:foreground_color_border]) - ax[:linecolor] = rgba_string(axis[:foreground_color_border]) + ax[:linecolor] = rgba_string(axis[:foreground_color_grid]) # lims lims = axis[:lims] diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d67abfcd..4100ccbf 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1064,8 +1064,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) lab[:set_family](axis[:tickfont].family) lab[:set_rotation](axis[:rotation]) end - if sp[:grid] - fgcolor = py_color(sp[:foreground_color_grid]) + if !(axis[:grid] in (nothing, false)) + fgcolor = py_color(axis[:foreground_color_grid]) pyaxis[:grid](true, color = fgcolor, linestyle = ":") ax[:set_axisbelow](true) end From 2dd99d053a3b65eff2797f1f13bdd796f1be5d01 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 10 Aug 2017 20:49:03 +0200 Subject: [PATCH 258/720] make it work on all backends --- src/backends/glvisualize.jl | 24 ++++++++++++++++++------ src/backends/gr.jl | 13 +++++++++---- src/backends/inspectdr.jl | 16 ++++++++++------ src/backends/pgfplots.jl | 12 ++++++++---- src/backends/plotly.jl | 8 ++++---- 5 files changed, 49 insertions(+), 24 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 3484131b..118db197 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -676,17 +676,29 @@ function text_model(font, pivot) end end function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area) - xticks, yticks, spine_segs, grid_segs = Plots.axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = Plots.axis_drawing_info(sp) xaxis = sp[:xaxis]; yaxis = sp[:yaxis] - c = Colors.color(Plots.gl_color(sp[:foreground_color_grid])) + xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid])) + ygc = Colors.color(Plots.gl_color(yaxis[:foreground_color_grid])) axis_vis = [] - if sp[:grid] - grid = draw_grid_lines(sp, grid_segs, 1f0, :dot, model, RGBA(c, 0.3f0)) + if !(xaxis[:grid] in (nothing, false)) + grid = draw_grid_lines(sp, xgrid_segs, 1f0, :dot, model, RGBA(xgc, 0.3f0)) push!(axis_vis, grid) end - if alpha(xaxis[:foreground_color_border]) > 0 - spine = draw_grid_lines(sp, spine_segs, 1f0, :solid, model, RGBA(c, 1.0f0)) + if !(yaxis[:grid] in (nothing, false)) + grid = draw_grid_lines(sp, ygrid_segs, 1f0, :dot, model, RGBA(ygc, 0.3f0)) + push!(axis_vis, grid) + end + + xac = Colors.color(Plots.gl_color(xaxis[:foreground_color_axis])) + yac = Colors.color(Plots.gl_color(yaxis[:foreground_color_axis])) + if alpha(xaxis[:foreground_color_axis]) > 0 + spine = draw_grid_lines(sp, xspine_segs, 1f0, :solid, model, RGBA(xac, 1.0f0)) + push!(axis_vis, spine) + end + if alpha(yaxis[:foreground_color_axis]) > 0 + spine = draw_grid_lines(sp, yspine_segs, 1f0, :solid, model, RGBA(yac, 1.0f0)) push!(axis_vis, spine) end fcolor = Plots.gl_color(xaxis[:foreground_color_axis]) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e2e42a26..a0a9171d 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -691,10 +691,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1]) # GR.setlinetype(GR.LINETYPE_DOTTED) - # if sp[:grid] - GR.grid3d(xtick, 0, ztick, xmin, ymax, zmin, 2, 0, 2) - GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) - # end + if !(xaxis[:grid] in (nothing, false)) + GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) + end + if !(yaxis[:grid] in (nothing, false)) + GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) + end + if !(zaxis[:grid] in (nothing, false)) + GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) + end GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index d7ef859c..1feda4ba 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -18,7 +18,8 @@ Add in functionality to Plots.jl: 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_grid, + :foreground_color_legend, :foreground_color_title, :foreground_color_axis, :foreground_color_border, :foreground_color_guide, :foreground_color_text, :label, :linecolor, :linestyle, :linewidth, :linealpha, @@ -334,15 +335,18 @@ end # --------------------------------------------------------------------------- function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) - 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] + xgrid_show = !(xaxis[:grid] in (nothing, false)) + ygrid_show = !(yaxis[:grid] in (nothing, false)) + + strip.grid = InspectDR.GridRect( + vmajor=xgrid_show, # vminor=xgrid_show, + hmajor=ygrid_show, # hminor=ygrid_show, + ) + plot.xscale = _inspectdr_getscale(xaxis[:scale], false) strip.yscale = _inspectdr_getscale(yaxis[:scale], true) xmin, xmax = axis_limits(xaxis) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index c44c10ae..cbbd645b 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -98,7 +98,7 @@ const _pgf_series_extrastyle = KW( :xsticks => "xcomb", ) -# PGFPlots uses the anchors to define orientations for example to align left +# PGFPlots uses the anchors to define orientations for example to align left # one needs to use the right edge as anchor const _pgf_annotation_halign = KW( :center => "", @@ -121,7 +121,7 @@ function pgf_color(grad::ColorGradient) end # Generates a colormap for pgfplots based on a ColorGradient -function pgf_colormap(grad::ColorGradient) +function pgf_colormap(grad::ColorGradient) join(map(grad.colors) do c @sprintf("rgb=(%.8f,%.8f,%.8f)", red(c), green(c),blue(c)) end,", ") @@ -266,6 +266,11 @@ function pgf_axis(sp::Subplot, letter) push!(style, "$(letter)majorticks=false") end + # grid on or off + if !(axis[:grid] in (nothing, false)) + push!(style, "$(letter)majorgrids = true") + end + # limits # TODO: support zlims if letter != :z @@ -324,7 +329,6 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:title] = "$(sp[:title])" end - sp[:grid] && push!(style, "grid = major") if sp[:aspect_ratio] in (1, :equal) kw[:axisEqual] = "true" end @@ -360,7 +364,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:colorbar] = "true" end # goto is needed to break out of col and series for - @goto colorbar_end + @goto colorbar_end end end end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 0a1e25aa..d558d941 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -5,8 +5,7 @@ const _plotly_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_guide, - :foreground_color_grid, - # :foreground_color_axis, + :foreground_color_grid, :foreground_color_axis, :foreground_color_text, :foreground_color_border, :foreground_color_title, :label, @@ -214,6 +213,7 @@ function plotly_axis(axis::Axis, sp::Subplot) letter = axis[:letter] ax = KW( :title => axis[:guide], + :gridcolor => rgba_string(axis[:foreground_color_grid]), :showgrid => !(axis[:grid] in (nothing, false)), :zeroline => false, :ticks => "inside", @@ -230,8 +230,8 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) - ax[:tickcolor] = rgba_string(axis[:foreground_color_border]) - ax[:linecolor] = rgba_string(axis[:foreground_color_grid]) + ax[:tickcolor] = rgba_string(axis[:foreground_color_axis]) + ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) # lims lims = axis[:lims] From 3c37de152d910fa8bbe63a7ef875ae9799cd739f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 10 Aug 2017 22:54:45 +0200 Subject: [PATCH 259/720] fix testimage 16 error - only add grid segments when ticks are defined --- src/axes.jl | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 6ac60b7c..cafee577 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -495,43 +495,33 @@ function axis_drawing_info(sp::Subplot) xgrid_segs = Segments(2) ygrid_segs = Segments(2) - f = scalefunc(yaxis[:scale]) - invf = invscalefunc(yaxis[:scale]) - t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) - t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - if !(xaxis[:ticks] in (nothing, false)) + f = scalefunc(yaxis[:scale]) + invf = invscalefunc(yaxis[:scale]) + t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) + t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) + push!(xspine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine # push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine for xtick in xticks[1] push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick # push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick + !(xaxis[:grid] in (nothing, false)) && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end end - if !(xaxis[:grid] in (nothing, false)) - for xtick in xticks[1] - push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid - end - end - - f = scalefunc(xaxis[:scale]) - invf = invscalefunc(xaxis[:scale]) - t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) - t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - if !(yaxis[:ticks] in (nothing, false)) + f = scalefunc(xaxis[:scale]) + invf = invscalefunc(xaxis[:scale]) + t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) + t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) + push!(yspine_segs, (xmin,ymin), (xmin,ymax)) # left spine # push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine for ytick in yticks[1] push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick # push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick - end - end - - if !(yaxis[:grid] in (nothing, false)) - for ytick in yticks[1] - push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + !(yaxis[:grid] in (nothing, false)) && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end end From 23ae99b97e119c889e3fedb67125bac7339374d5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 11 Aug 2017 12:57:11 +0200 Subject: [PATCH 260/720] undo support for foreground_color_grid and foreground_color_axis attributes in plotly(js) --- src/backends/plotly.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index d558d941..cc0aed9c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -5,7 +5,7 @@ const _plotly_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_guide, - :foreground_color_grid, :foreground_color_axis, + # :foreground_color_grid, :foreground_color_axis, :foreground_color_text, :foreground_color_border, :foreground_color_title, :label, @@ -213,7 +213,6 @@ function plotly_axis(axis::Axis, sp::Subplot) letter = axis[:letter] ax = KW( :title => axis[:guide], - :gridcolor => rgba_string(axis[:foreground_color_grid]), :showgrid => !(axis[:grid] in (nothing, false)), :zeroline => false, :ticks => "inside", @@ -230,8 +229,8 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) - ax[:tickcolor] = rgba_string(axis[:foreground_color_axis]) - ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) + ax[:tickcolor] = rgba_string(axis[:foreground_color_border]) + ax[:linecolor] = rgba_string(axis[:foreground_color_border]) # lims lims = axis[:lims] From ad2eaf7aef672fb9081ce4c632432704162babb8 Mon Sep 17 00:00:00 2001 From: JackDevine Date: Tue, 15 Aug 2017 20:10:02 +1200 Subject: [PATCH 261/720] Add stride to wireframe/surface I only have this for PyPlot at the moment, I would be more than happy to add other backends if people find it useful. Also, if people have any ideas for aliases, then I would be happy to do that too. --- src/args.jl | 2 ++ src/backends/pyplot.jl | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index ea4f8627..f60e782c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -214,6 +214,8 @@ const _series_defaults = KW( :primary => true, # when true, this "counts" as a series for color selection, etc. the main use is to allow # one logical series to be broken up (path and markers, for example) :hover => nothing, # text to display when hovering over the data points + :rstride => 1, # array row stride for wireframe/surface + :cstride => 1, # array column stride for wireframe/surface ) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d67abfcd..ed3d5c95 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -31,6 +31,8 @@ const _pyplot_attr = merge_with_base_supported([ :inset_subplots, :dpi, :colorbar_title, + :rstride, + :cstride, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -702,8 +704,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z; label = series[:label], zorder = series[:series_plotindex], - rstride = 1, - cstride = 1, + rstride = series[:rstride], + cstride = series[:cstride], linewidth = py_dpi_scale(plt, series[:linewidth]), edgecolor = py_linecolor(series), extrakw... From 33a15f1e9386eaf3dedbe1e14e6feb1dda17b7a9 Mon Sep 17 00:00:00 2001 From: Martin Biel Date: Tue, 15 Aug 2017 18:03:57 +0200 Subject: [PATCH 262/720] Process user recipes depth-first rather than breadth-first to enforce the plot order given in the recipe --- src/pipeline.jl | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index 83eff845..231caa45 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -60,29 +60,26 @@ function _process_userrecipes(plt::Plot, d::KW, args) args = _preprocess_args(d, args, still_to_process) # for plotting recipes, swap out the args and update the parameter dictionary - # we are keeping a queue of series that still need to be processed. + # we are keeping a stack of series that still need to be processed. # each pass through the loop, we pop one off and apply the recipe. # the recipe will return a list a Series objects... the ones that are - # finished (no more args) get added to the kw_list, and the rest go into the queue - # for processing. + # finished (no more args) get added to the kw_list, the ones that are not + # are placed on top of the stack and are then processed further. kw_list = KW[] while !isempty(still_to_process) - # grab the first in line to be processed and pass it through apply_recipe - # to generate a list of RecipeData objects (data + attributes) + # grab the first in line to be processed and either add it to the kw_list or + # pass it through apply_recipe to generate a list of RecipeData objects (data + attributes) + # for further processing. next_series = shift!(still_to_process) - rd_list = RecipesBase.apply_recipe(next_series.d, next_series.args...) - for recipedata in rd_list - # recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes - if !(typeof(recipedata) <: RecipeData) - error("Inputs couldn't be processed... expected RecipeData but got: $recipedata") - end - - if isempty(recipedata.args) - _process_userrecipe(plt, kw_list, recipedata) - else - # args are non-empty, so there's still processing to do... add it back to the queue - push!(still_to_process, recipedata) - end + # recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes + if !(typeof(next_series) <: RecipeData) + error("Inputs couldn't be processed... expected RecipeData but got: $recipedata") + end + if isempty(next_series.args) + _process_userrecipe(plt, kw_list, next_series) + else + rd_list = RecipesBase.apply_recipe(next_series.d, next_series.args...) + prepend!(still_to_process,rd_list) end end From 177d380092f65bcff318f67b92d2c127841db2cc Mon Sep 17 00:00:00 2001 From: JackDevine Date: Wed, 16 Aug 2017 10:18:26 +1200 Subject: [PATCH 263/720] Added suggestions Changed the interface to stride, which is a tuple. Also added aliases and a docstring in arg_desc. --- src/arg_desc.jl | 1 + src/args.jl | 4 ++-- src/backends/pyplot.jl | 7 +++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f244ff99..b7af05d9 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -48,6 +48,7 @@ const _arg_desc = KW( :series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", :primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.", :hover => "nothing or vector of strings. Text to display when hovering over each data point.", +:stride => "(1,1). Array row and column strides. Used in surface/wireframe." # plot args :plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)", diff --git a/src/args.jl b/src/args.jl index f60e782c..a72183b0 100644 --- a/src/args.jl +++ b/src/args.jl @@ -214,8 +214,7 @@ const _series_defaults = KW( :primary => true, # when true, this "counts" as a series for color selection, etc. the main use is to allow # one logical series to be broken up (path and markers, for example) :hover => nothing, # text to display when hovering over the data points - :rstride => 1, # array row stride for wireframe/surface - :cstride => 1, # array column stride for wireframe/surface + :stride, => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride. ) @@ -471,6 +470,7 @@ add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesa add_aliases(:html_output_format, :format, :fmt, :html_format) add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) +add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str) # add all pluralized forms to the _keyAliases dict diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ed3d5c95..ecac853a 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -31,8 +31,7 @@ const _pyplot_attr = merge_with_base_supported([ :inset_subplots, :dpi, :colorbar_title, - :rstride, - :cstride, + :stride, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -704,8 +703,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z; label = series[:label], zorder = series[:series_plotindex], - rstride = series[:rstride], - cstride = series[:cstride], + rstride = series[:stride][1], + cstride = series[:stride][2], linewidth = py_dpi_scale(plt, series[:linewidth]), edgecolor = py_linecolor(series), extrakw... From d1dcd536f58d54a30009102fc63f201844c4df9f Mon Sep 17 00:00:00 2001 From: JackDevine Date: Wed, 16 Aug 2017 10:41:19 +1200 Subject: [PATCH 264/720] I forgot a comma --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index b7af05d9..50cf0a45 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -48,7 +48,7 @@ const _arg_desc = KW( :series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", :primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.", :hover => "nothing or vector of strings. Text to display when hovering over each data point.", -:stride => "(1,1). Array row and column strides. Used in surface/wireframe." +:stride => "(1,1). Array row and column strides. Used in surface/wireframe.", # plot args :plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)", From 774187257808bb7438da44416edccba8fbbbc5cc Mon Sep 17 00:00:00 2001 From: JackDevine Date: Wed, 16 Aug 2017 11:20:04 +1200 Subject: [PATCH 265/720] Comma in the wrong place --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index a72183b0..223e7484 100644 --- a/src/args.jl +++ b/src/args.jl @@ -214,7 +214,7 @@ const _series_defaults = KW( :primary => true, # when true, this "counts" as a series for color selection, etc. the main use is to allow # one logical series to be broken up (path and markers, for example) :hover => nothing, # text to display when hovering over the data points - :stride, => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride. + :stride => (1,1), # array stride for wireframe/surface, the first element is the row stride and the second is the column stride. ) From a1d0d028b6e4a38917a8b6f2200696daba2d7646 Mon Sep 17 00:00:00 2001 From: Martin Biel Date: Wed, 16 Aug 2017 10:16:37 +0200 Subject: [PATCH 266/720] Updated error text in _process_userrecipes, now uses correct variable --- src/pipeline.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index 231caa45..8879ff6f 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -73,7 +73,7 @@ function _process_userrecipes(plt::Plot, d::KW, args) next_series = shift!(still_to_process) # recipedata should be of type RecipeData. if it's not then the inputs must not have been fully processed by recipes if !(typeof(next_series) <: RecipeData) - error("Inputs couldn't be processed... expected RecipeData but got: $recipedata") + error("Inputs couldn't be processed... expected RecipeData but got: $next_series") end if isempty(next_series.args) _process_userrecipe(plt, kw_list, next_series) From e0c679f5ee820754bb1664098afca5c959e9892f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 16 Aug 2017 17:45:32 +0200 Subject: [PATCH 267/720] magic grid argument --- src/Plots.jl | 4 +-- src/arg_desc.jl | 8 +++-- src/args.jl | 70 +++++++++++++++++++++++++++++++++++++ src/axes.jl | 4 +-- src/backends/glvisualize.jl | 11 +++--- src/backends/gr.jl | 27 ++++++-------- src/backends/inspectdr.jl | 4 +-- src/backends/pgfplots.jl | 2 +- src/backends/plotly.jl | 13 ++++--- src/backends/pyplot.jl | 11 ++++-- src/examples.jl | 12 +++++++ 11 files changed, 127 insertions(+), 39 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index d320df7c..2e504051 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -215,8 +215,8 @@ xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...) xaxis!(args...; kw...) = plot!(; xaxis = args, kw...) yaxis!(args...; kw...) = plot!(; yaxis = args, kw...) -xgrid!(grid::Bool = true; kw...) = plot!(; xgrid = grid, kw...) -ygrid!(grid::Bool = true; kw...) = plot!(; ygrid = grid, kw...) +xgrid!(args...; kw...) = plot!(; xgrid = args, kw...) +ygrid!(args...; kw...) = plot!(; ygrid = args, kw...) let PlotOrSubplot = Union{Plot, Subplot} title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 571400a7..ee1e99d8 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -76,7 +76,6 @@ const _arg_desc = KW( :background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).", :foreground_color_subplot => "Color Type or `:match` (matches `:foreground_color`). Base foreground color of the subplot.", :foreground_color_legend => "Color Type or `:match` (matches `:foreground_color_subplot`). Foreground color of the legend.", -:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.", :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", @@ -110,6 +109,9 @@ const _arg_desc = KW( :foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.", :foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).", :mirror => "Bool. Switch the side of the tick labels (right or top).", -:grid => "Bool. Show the grid lines?", - +:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`", +:foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.", +:gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.", +:gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", +:gridlinewidth => "Number. Width of the grid lines (in pixels)", ) diff --git a/src/args.jl b/src/args.jl index 0012bc7e..01cafb51 100644 --- a/src/args.jl +++ b/src/args.jl @@ -163,6 +163,24 @@ const _scaleAliases = Dict{Symbol,Symbol}( :log => :log10, ) +const _allGridSyms = [:x, :y, :z, + :xy, :xz, :yx, :yz, :zx, :zy, + :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, + :all, :both, :on, + :none, :off,] +const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing; false; true] +hasgrid(arg::Void, letter) = false +hasgrid(arg::Bool, letter) = arg +function hasgrid(arg::Symbol, letter) + if arg in _allGridSyms + arg in (:all, :both, :on) || contains(string(arg), string(letter)) + else + warn("Unknown grid argument $arg; $letter\grid was set to `true` instead") + true + end +end +hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) + # ----------------------------------------------------------------------------- const _series_defaults = KW( @@ -285,6 +303,9 @@ const _axis_defaults = KW( :mirror => false, :grid => true, :foreground_color_grid => :match, # grid color + :gridalpha => 0.3, + :gridstyle => :dot, + :gridlinewidth => 1, ) const _suppress_warnings = Set{Symbol}([ @@ -414,6 +435,7 @@ add_aliases(:linealpha, :la, :lalpha, :lα, :lineopacity, :lopacity) add_aliases(:markeralpha, :ma, :malpha, :mα, :markeropacity, :mopacity) add_aliases(:markerstrokealpha, :msa, :msalpha, :msα, :markerstrokeopacity, :msopacity) add_aliases(:fillalpha, :fa, :falpha, :fα, :fillopacity, :fopacity) +add_aliases(:gridalpha, :ga, :galpha, :gα, :gridopacity, :gopacity) # series attributes add_aliases(:seriestype, :st, :t, :typ, :linetype, :lt) @@ -469,6 +491,8 @@ add_aliases(:series_annotations, :series_ann, :seriesann, :series_anns, :seriesa add_aliases(:html_output_format, :format, :fmt, :html_format) add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) +add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) +add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) # add all pluralized forms to the _keyAliases dict @@ -645,6 +669,36 @@ function processFillArg(d::KW, arg) return end + +function processGridArg!(d::KW, arg, letter) + if arg in _allGridArgs + d[Symbol(letter, :grid)] = hasgrid(arg, letter) + + elseif allStyles(arg) + d[Symbol(letter, :gridstyle)] = arg + + elseif typeof(arg) <: Stroke + arg.width == nothing || (d[Symbol(letter, :gridlinewidth)] = arg.width) + arg.color == nothing || (d[Symbol(letter, :foreground_color_grid)] = arg.color in (:auto, :match) ? :match : plot_color(arg.color)) + arg.alpha == nothing || (d[Symbol(letter, :gridalpha)] = arg.alpha) + arg.style == nothing || (d[Symbol(letter, :gridstyle)] = arg.style) + + # linealpha + elseif allAlphas(arg) + d[Symbol(letter, :gridalpha)] = arg + + # linewidth + elseif allReals(arg) + d[Symbol(letter, :gridlinewidth)] = arg + + # color +elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid)) + warn("Skipped grid arg $arg.") + + end +end + + _replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape) _replace_markershape(shapes::AVec) = map(_replace_markershape, shapes) _replace_markershape(shape) = shape @@ -688,6 +742,22 @@ function preprocessArgs!(d::KW) end end + # handle grid args common to all axes + args = pop!(d, :grid, ()) + for arg in wraptuple(args) + for letter in (:x, :y, :z) + processGridArg!(d, arg, letter) + end + end + # handle individual axes grid args + for letter in (:x, :y, :z) + gridsym = Symbol(letter, :grid) + args = pop!(d, gridsym, ()) + for arg in wraptuple(args) + processGridArg!(d, arg, letter) + end + end + # handle line args for arg in wraptuple(pop!(d, :line, ())) processLineArg(d, arg) diff --git a/src/axes.jl b/src/axes.jl index cafee577..734f2154 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -506,7 +506,7 @@ function axis_drawing_info(sp::Subplot) for xtick in xticks[1] push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick # push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick - !(xaxis[:grid] in (nothing, false)) && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end end @@ -521,7 +521,7 @@ function axis_drawing_info(sp::Subplot) for ytick in yticks[1] push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick # push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick - !(yaxis[:grid] in (nothing, false)) && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 118db197..60c1730a 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -24,7 +24,8 @@ const _glvisualize_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, + :grid, :gridalpha, :gridstyle, :gridlinewidth, + :legend, :colorbar, :marker_z, :line_z, :levels, @@ -682,12 +683,12 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid])) ygc = Colors.color(Plots.gl_color(yaxis[:foreground_color_grid])) axis_vis = [] - if !(xaxis[:grid] in (nothing, false)) - grid = draw_grid_lines(sp, xgrid_segs, 1f0, :dot, model, RGBA(xgc, 0.3f0)) + if xaxis[:grid] + grid = draw_grid_lines(sp, xgrid_segs, xaxis[:gridlinewidth], xaxis[:gridstyle], model, RGBA(xgc, xaxis[:gridalpha])) push!(axis_vis, grid) end - if !(yaxis[:grid] in (nothing, false)) - grid = draw_grid_lines(sp, ygrid_segs, 1f0, :dot, model, RGBA(ygc, 0.3f0)) + if yaxis[:grid] + grid = draw_grid_lines(sp, ygrid_segs, yaxis[:gridlinewidth], yaxis[:gridstyle], model, RGBA(ygc, yaxis[:gridalpha])) push!(axis_vis, grid) end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index a0a9171d..061dee7f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -20,7 +20,8 @@ const _gr_attr = merge_with_base_supported([ :title, :window_title, :guide, :lims, :ticks, :scale, :flip, :tickfont, :guidefont, :legendfont, - :grid, :legend, :legendtitle, :colorbar, + :grid, :gridalpha, :gridstyle, :gridlinewidth, + :legend, :legendtitle, :colorbar, :marker_z, :levels, :ribbon, :quiver, :orientation, @@ -691,15 +692,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1]) # GR.setlinetype(GR.LINETYPE_DOTTED) - if !(xaxis[:grid] in (nothing, false)) - GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) - end - if !(yaxis[:grid] in (nothing, false)) - GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) - end - if !(zaxis[:grid] in (nothing, false)) - GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) - end + xaxis[:grid] && GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) + yaxis[:grid] && GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) + zaxis[:grid] && GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) @@ -718,16 +713,16 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # @show xticks yticks #spine_segs grid_segs # draw the grid lines - if !(xaxis[:grid] in (nothing, false)) + if xaxis[:grid] # gr_set_linecolor(sp[:foreground_color_grid]) # GR.grid(xtick, ytick, 0, 0, majorx, majory) - gr_set_line(1, :dot, xaxis[:foreground_color_grid]) - GR.settransparency(0.5) + gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) + GR.settransparency(xaxis[:gridalpha]) gr_polyline(coords(xgrid_segs)...) end - if !(yaxis[:grid] in (nothing, false)) - gr_set_line(1, :dot, yaxis[:foreground_color_grid]) - GR.settransparency(0.5) + if yaxis[:grid] + gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) + GR.settransparency(yaxis[:gridalpha]) gr_polyline(coords(ygrid_segs)...) end GR.settransparency(1.0) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 1feda4ba..a8224634 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -339,8 +339,8 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) const strip = plot.strips[1] #Only 1 strip supported with Plots.jl xaxis = sp[:xaxis]; yaxis = sp[:yaxis] - xgrid_show = !(xaxis[:grid] in (nothing, false)) - ygrid_show = !(yaxis[:grid] in (nothing, false)) + xgrid_show = xaxis[:grid] + ygrid_show = yaxis[:grid] strip.grid = InspectDR.GridRect( vmajor=xgrid_show, # vminor=xgrid_show, diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index cbbd645b..30169147 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -267,7 +267,7 @@ function pgf_axis(sp::Subplot, letter) end # grid on or off - if !(axis[:grid] in (nothing, false)) + if axis[:grid] push!(style, "$(letter)majorgrids = true") end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index cc0aed9c..9e0537ce 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -5,7 +5,7 @@ const _plotly_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, :foreground_color_legend, :foreground_color_guide, - # :foreground_color_grid, :foreground_color_axis, + :foreground_color_grid, :foreground_color_axis, :foreground_color_text, :foreground_color_border, :foreground_color_title, :label, @@ -19,7 +19,8 @@ const _plotly_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :colorbar, :colorbar_title, + :grid, :gridalpha, :gridlinewidth, + :legend, :colorbar, :colorbar_title, :marker_z, :fill_z, :levels, :ribbon, :quiver, :orientation, @@ -213,7 +214,9 @@ function plotly_axis(axis::Axis, sp::Subplot) letter = axis[:letter] ax = KW( :title => axis[:guide], - :showgrid => !(axis[:grid] in (nothing, false)), + :showgrid => axis[:grid], + :gridcolor => rgba_string(plot_color(axis[:foreground_color_grid], axis[:gridalpha])), + :gridwidth => axis[:gridlinewidth], :zeroline => false, :ticks => "inside", ) @@ -229,8 +232,8 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) - ax[:tickcolor] = rgba_string(axis[:foreground_color_border]) - ax[:linecolor] = rgba_string(axis[:foreground_color_border]) + ax[:tickcolor] = rgba_string(axis[:foreground_color_axis]) + ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) # lims lims = axis[:lims] diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 4100ccbf..4b185e6e 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -17,7 +17,8 @@ const _pyplot_attr = merge_with_base_supported([ :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, - :grid, :legend, :legendtitle, :colorbar, + :grid, :gridalpha, :gridstyle, :gridlinewidth, + :legend, :legendtitle, :colorbar, :marker_z, :line_z, :fill_z, :levels, :ribbon, :quiver, :arrow, @@ -1064,9 +1065,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) lab[:set_family](axis[:tickfont].family) lab[:set_rotation](axis[:rotation]) end - if !(axis[:grid] in (nothing, false)) + if axis[:grid] fgcolor = py_color(axis[:foreground_color_grid]) - pyaxis[:grid](true, color = fgcolor, linestyle = ":") + pyaxis[:grid](true, + color = fgcolor, + linestyle = py_linestyle(:line, axis[:gridstyle]), + linewidth = axis[:gridlinewidth], + alpha = axis[:gridalpha]) ax[:set_axisbelow](true) end py_set_axis_colors(ax, axis) diff --git a/src/examples.jl b/src/examples.jl index a9b86960..640dde92 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -329,6 +329,18 @@ PlotExample("Spy", end)] ), +PlotExample("Magic grid argument", + "The grid lines can be modified individually for each axis with the magic grid argument", + [:(begin + x = rand(10) + p1 = plot(x, title = "Default looks") + p2 = plot(x, grid = (:y, :olivedrab, :solid, 0.5), title = "Modified y grid") + p3 = plot(deepcopy(p2), title = "Add x grid") + xgrid!(p3, :on, :cadetblue, 2, :dashdot) + plot(p1, p2, p3, layout = (1, 3), label = "", fillrange = 0, fillalpha = 0.3) + end)] +), + ] # --------------------------------------------------------------------------------- From 682ba1f7640ce007540f921f4de345f39de29111 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 16 Aug 2017 19:41:13 +0200 Subject: [PATCH 268/720] allow non-boolean args for xgrid function --- src/Plots.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 2e504051..32340a10 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -234,8 +234,8 @@ let PlotOrSubplot = Union{Plot, Subplot} ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; xticks = (ticks,labels), kw...) yticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot, ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; yticks = (ticks,labels), kw...) - xgrid!(plt::PlotOrSubplot, grid::Bool = true; kw...) = plot!(plt; xgrid = grid, kw...) - ygrid!(plt::PlotOrSubplot, grid::Bool = true; kw...) = plot!(plt; ygrid = grid, kw...) + xgrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; xgrid = args, kw...) + ygrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; ygrid = args, kw...) annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...) annotate!{T<:Tuple}(plt::PlotOrSubplot, anns::AVec{T}; kw...) = plot!(plt; annotation = anns, kw...) xflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; xflip = flip, kw...) From bb2f4ff16b97f44c2dae7f6204b694ce7cd122d6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 16 Aug 2017 21:05:05 +0200 Subject: [PATCH 269/720] import inplace plot placeholder from RecipesBase --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index e7c7fc66..4f104ea6 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -8,7 +8,7 @@ import StaticArrays using StaticArrays.FixedSizeArrays @reexport using RecipesBase -import RecipesBase: plot, animate +import RecipesBase: plot, plot!, animate using Base.Meta @reexport using PlotUtils @reexport using PlotThemes From 8288e85c2567788301d9c6e79fb802333695e86e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 16 Aug 2017 22:32:00 +0200 Subject: [PATCH 270/720] only flip colorbar for marker_z --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 80b52822..4716aa8e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -336,6 +336,7 @@ function gr_draw_markers(series::Series, x, y) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_draw_markers(series, x, y, series[:markersize], mz) if mz != nothing + GR.setscale(0) gr_colorbar(series[:subplot]) end end @@ -863,7 +864,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:marker_z] != nothing zmin, zmax = extrema(series[:marker_z]) GR.setspace(zmin, zmax, 0, 90) - GR.setscale(0) end gr_draw_markers(series, x, y) end From 4b60b05f757b274cf2a037c5ca8f1fe14dc05bbe Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 17 Aug 2017 13:42:54 +0200 Subject: [PATCH 271/720] update grid defaults and modify grid example --- src/args.jl | 8 ++++---- src/examples.jl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/args.jl b/src/args.jl index 01cafb51..e68e6be6 100644 --- a/src/args.jl +++ b/src/args.jl @@ -175,7 +175,7 @@ function hasgrid(arg::Symbol, letter) if arg in _allGridSyms arg in (:all, :both, :on) || contains(string(arg), string(letter)) else - warn("Unknown grid argument $arg; $letter\grid was set to `true` instead") + warn("Unknown grid argument $arg; $letter\grid was set to `true` instead.") true end end @@ -303,9 +303,9 @@ const _axis_defaults = KW( :mirror => false, :grid => true, :foreground_color_grid => :match, # grid color - :gridalpha => 0.3, - :gridstyle => :dot, - :gridlinewidth => 1, + :gridalpha => 0.1, + :gridstyle => :solid, + :gridlinewidth => 0.5, ) const _suppress_warnings = Set{Symbol}([ diff --git a/src/examples.jl b/src/examples.jl index 640dde92..87ae1ca4 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -321,7 +321,7 @@ PlotExample("Animation with subplots", ), PlotExample("Spy", - "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`", + "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`.", [:(begin a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) @@ -330,13 +330,13 @@ PlotExample("Spy", ), PlotExample("Magic grid argument", - "The grid lines can be modified individually for each axis with the magic grid argument", + "The grid lines can be modified individually for each axis with the magic grid argument.", [:(begin x = rand(10) p1 = plot(x, title = "Default looks") - p2 = plot(x, grid = (:y, :olivedrab, :solid, 0.5), title = "Modified y grid") + p2 = plot(x, grid = (:y, :olivedrab, :dot, 1, 0.9), title = "Modified y grid") p3 = plot(deepcopy(p2), title = "Add x grid") - xgrid!(p3, :on, :cadetblue, 2, :dashdot) + xgrid!(p3, :on, :cadetblue, 2, :dashdot, 0.4) plot(p1, p2, p3, layout = (1, 3), label = "", fillrange = 0, fillalpha = 0.3) end)] ), From 42f54b8df949d49dca9664989ea56bc658f323a5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 17 Aug 2017 14:10:04 +0200 Subject: [PATCH 272/720] remove Bools from _allGridArgs --- src/args.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index e68e6be6..d861fea3 100644 --- a/src/args.jl +++ b/src/args.jl @@ -168,7 +168,7 @@ const _allGridSyms = [:x, :y, :z, :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, :all, :both, :on, :none, :off,] -const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing; false; true] +const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing] hasgrid(arg::Void, letter) = false hasgrid(arg::Bool, letter) = arg function hasgrid(arg::Symbol, letter) @@ -671,7 +671,7 @@ end function processGridArg!(d::KW, arg, letter) - if arg in _allGridArgs + if arg in _allGridArgs || isa(arg, Bool) d[Symbol(letter, :grid)] = hasgrid(arg, letter) elseif allStyles(arg) From 4be0093a8a41bd1136c2388e9596810be91c6e9f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 18 Aug 2017 00:34:15 +0200 Subject: [PATCH 273/720] prepare release --- NEWS.md | 13 +++++++++++-- src/Plots.jl | 2 +- test/imgcomp.jl | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 8113ae7b..8a7e19d7 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,14 +11,23 @@ --- ## (current master) -## 0.12.2 +## 0.12.3 + +- new grid line style defaults +- `grid` is now an axis attribute and a magic argument: it is now possible to modify the grid line style, alpha and line width +- Enforce plot order in user recipes +- import `plot!` from RecipesBase +- GR no longer automatically handles _ and ^ in texts +- fix GR colorbar for scatter plots + +#### 0.12.2 - fix an issue with Juno/PlotlyJS compatibility on new installations - fix markers not showing up in seriesrecipes using :scatter - don't use pywrap in the pyplot backend - improve the bottom margin for the gr backend -## 0.12.1 +#### 0.12.1 - fix deprecation warnings - switch from FixedSizeArrays to StaticArrays.FixedSizeArrays diff --git a/src/Plots.jl b/src/Plots.jl index e7c7fc66..625dba5e 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 7d6ae303..f3c0ee22 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.12.1" +const _current_plots_version = v"0.12.3" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 4c1c0922346c08708c595e02fa99c248f007bb08 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 18 Aug 2017 00:46:02 +0200 Subject: [PATCH 274/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 625dba5e..e7c7fc66 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 66ce38d94851eb83622be9975c5af426dd0e57ae Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 15 Aug 2017 23:02:31 +0200 Subject: [PATCH 275/720] Specified some docstrings --- src/Plots.jl | 32 +++++++++++++++++++++++++++++++- src/args.jl | 1 - src/backends.jl | 3 +++ src/components.jl | 12 ++++++++++++ src/layouts.jl | 12 ++++++++++++ src/output.jl | 12 ++++++++++++ src/plot.jl | 4 ++++ src/subplots.jl | 5 +++++ src/themes.jl | 4 ++++ src/utils.jl | 21 ++++++++++++++++++++- 10 files changed, 103 insertions(+), 3 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index bca0d9c9..c75a8e65 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -188,32 +188,62 @@ include("output.jl") @shorthands quiver @shorthands curves +"Plot a pie diagram" pie(args...; kw...) = plot(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing) pie!(args...; kw...) = plot!(args...; kw..., seriestype = :pie, aspect_ratio = :equal, grid=false, xticks=nothing, yticks=nothing) + +"Plot with seriestype :path3d" plot3d(args...; kw...) = plot(args...; kw..., seriestype = :path3d) plot3d!(args...; kw...) = plot!(args...; kw..., seriestype = :path3d) - +"Add title to an existing plot" title!(s::AbstractString; kw...) = plot!(; title = s, kw...) + +"Add xlabel to an existing plot" xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...) + +"Add ylabel to an existing plot" ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...) + +"Set xlims for an existing plot" xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; xlims = lims, kw...) + +"Set ylims for an existing plot" ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; ylims = lims, kw...) + +"Set zlims for an existing plot" zlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; zlims = lims, kw...) + xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...) ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...) zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmin,zmax), kw...) + + +"Set xticks for an existing plot" xticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; xticks = v, kw...) + +"Set yticks for an existing plot" yticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; yticks = v, kw...) + xticks!{T<:Real,S<:AbstractString}( ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; xticks = (ticks,labels), kw...) yticks!{T<:Real,S<:AbstractString}( ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; yticks = (ticks,labels), kw...) + +"Add annotations to an existing plot" annotate!(anns...; kw...) = plot!(; annotation = anns, kw...) annotate!{T<:Tuple}(anns::AVec{T}; kw...) = plot!(; annotation = anns, kw...) + +"Flip the current plots' x axis" xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...) + +"Flip the current plots' y axis" yflip!(flip::Bool = true; kw...) = plot!(; yflip = flip, kw...) + +"Specify x axis attributes for an existing plot" xaxis!(args...; kw...) = plot!(; xaxis = args, kw...) + +"Specify x axis attributes for an existing plot" yaxis!(args...; kw...) = plot!(; yaxis = args, kw...) xgrid!(args...; kw...) = plot!(; xgrid = args, kw...) ygrid!(args...; kw...) = plot!(; ygrid = args, kw...) diff --git a/src/args.jl b/src/args.jl index d861fea3..37dd250e 100644 --- a/src/args.jl +++ b/src/args.jl @@ -512,7 +512,6 @@ end `default(; kw...)` will set the current default value for each key/value pair `default(d, key)` returns the key from d if it exists, otherwise `default(key)` """ - function default(k::Symbol) k = get(_keyAliases, k, k) for defaults in _all_defaults diff --git a/src/backends.jl b/src/backends.jl index 19a9c6ea..b445807c 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -6,7 +6,10 @@ const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none) const _backends = Symbol[] const _initialized_backends = Set{Symbol}() +"Returns a list of supported backends" backends() = _backends + +"Returns the name of the current backend" backend_name() = CURRENT_BACKEND.sym _backend_instance(sym::Symbol) = haskey(_backendType, sym) ? _backendType[sym]() : error("Unsupported backend $sym") diff --git a/src/components.jl b/src/components.jl index 2962f184..0ffe6226 100644 --- a/src/components.jl +++ b/src/components.jl @@ -22,6 +22,13 @@ immutable Shape # end # end end + +""" + Shape(x, y) + Shape(vertices) + +Construct a polygon to be plotted +""" Shape(verts::AVec) = Shape(unzip(verts)...) Shape(s::Shape) = deepcopy(s) @@ -331,6 +338,11 @@ immutable PlotText end PlotText(str) = PlotText(string(str), font()) +""" + text(string, args...) + +Create a PlotText object wrapping a string with font info, for plot annotations +""" text(t::PlotText) = t text(str::AbstractString, f::Font) = PlotText(str, f) function text(str, args...) diff --git a/src/layouts.jl b/src/layouts.jl index 71f8b7a1..9e90a2f1 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -133,7 +133,12 @@ make_measure_hor(m::Measure) = m make_measure_vert(n::Number) = n * h make_measure_vert(m::Measure) = m +""" + bbox(x, y, w, h [,originargs...]) + bbox(layout) +Create a bounding box for plotting +""" function bbox(x, y, w, h, oarg1::Symbol, originargs::Symbol...) oargs = vcat(oarg1, originargs...) orighor = :left @@ -253,6 +258,13 @@ type GridLayout <: AbstractLayout attr::KW end +""" + grid(args...; kw...) + +Create a grid layout for subplots. `args` specify the dimensions, e.g. +`grid(3,2, widths = (0.6,04))` creates a grid with three rows and two +columns of different width. +""" grid(args...; kw...) = GridLayout(args...; kw...) function GridLayout(dims...; diff --git a/src/output.jl b/src/output.jl index 5c036fe7..14f15c30 100644 --- a/src/output.jl +++ b/src/output.jl @@ -97,6 +97,13 @@ function addExtension(fn::AbstractString, ext::AbstractString) end end +""" + savefig([plot,] filename) + +Save a Plot (the current plot if `plot` is not passed) to file. The file +type is inferred from the file extension. All backends support png and pdf +file types, some also support svg, ps, eps, html and tex. +""" function savefig(plt::Plot, fn::AbstractString) # get the extension @@ -119,7 +126,11 @@ savefig(fn::AbstractString) = savefig(current(), fn) # --------------------------------------------------------- +""" + gui([plot]) +Display a plot using the backends' gui window +""" gui(plt::Plot = current()) = display(PlotsDisplay(), plt) # IJulia only... inline display @@ -198,6 +209,7 @@ for mime in keys(_mimeformats) end end +"Close all open gui windows of the current backend" closeall() = closeall(backend()) diff --git a/src/plot.jl b/src/plot.jl index 3ab41701..3e6dd9a3 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -6,6 +6,10 @@ const CURRENT_PLOT = CurrentPlot(Nullable{AbstractPlot}()) isplotnull() = isnull(CURRENT_PLOT.nullableplot) +""" + current() +Returns the Plot object for the current plot +""" function current() if isplotnull() error("No current plot/subplot") diff --git a/src/subplots.jl b/src/subplots.jl index ccd1478c..5629125f 100644 --- a/src/subplots.jl +++ b/src/subplots.jl @@ -13,6 +13,11 @@ function Subplot{T<:AbstractBackend}(::T; parent = RootLayout()) ) end +""" + plotarea(subplot) + +Return the bounding box of a subplot +""" plotarea(sp::Subplot) = sp.plotarea plotarea!(sp::Subplot, bbox::BoundingBox) = (sp.plotarea = bbox) diff --git a/src/themes.jl b/src/themes.jl index e7a39d02..840078dd 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -1,4 +1,8 @@ +""" + theme(s::Symbol) +Specify the colour theme for plots. +""" function theme(s::Symbol; kw...) # reset? if s == :none || s == :default diff --git a/src/utils.jl b/src/utils.jl index d8aced3d..6add802a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -500,9 +500,28 @@ end function get_sp_lims(sp::Subplot, letter::Symbol) axis_limits(sp[Symbol(letter, :axis)]) end + +""" + xlims([plt]) + +Returns the x axis limits of the current plot or subplot +""" xlims(sp::Subplot) = get_sp_lims(sp, :x) + +""" + ylims([plt]) + +Returns the y axis limits of the current plot or subplot +""" ylims(sp::Subplot) = get_sp_lims(sp, :y) + +""" + zlims([plt]) + +Returns the z axis limits of the current plot or subplot +""" zlims(sp::Subplot) = get_sp_lims(sp, :z) + xlims(plt::Plot, sp_idx::Int = 1) = xlims(plt[sp_idx]) ylims(plt::Plot, sp_idx::Int = 1) = ylims(plt[sp_idx]) zlims(plt::Plot, sp_idx::Int = 1) = zlims(plt[sp_idx]) @@ -536,7 +555,7 @@ allFunctions(arg) = trueOrAllTrue(a -> isa(a, Function), arg) """ Allows temporary setting of backend and defaults for Plots. Settings apply only for the `do` block. Example: ``` -with(:gadfly, size=(400,400), type=:histogram) do +with(:gr, size=(400,400), type=:histogram) do plot(rand(10)) plot(rand(10)) end From db82f223204851b50a6718a0cb7bb184b3a28b22 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 16 Aug 2017 11:21:44 +0200 Subject: [PATCH 276/720] add the last docstrings --- src/animation.jl | 9 +++++++-- src/components.jl | 17 ++++++++++++++++- src/examples.jl | 7 +++++++ src/plotattr.jl | 6 ++++++ src/recipes.jl | 1 + src/utils.jl | 3 ++- 6 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 55a9fe53..4afa01cf 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -1,4 +1,4 @@ - +"Represents an animation object" immutable Animation dir::String frames::Vector{String} @@ -9,6 +9,11 @@ function Animation() Animation(tmpdir, String[]) end +""" + frame(animation[, plot]) + +Add a plot (the current plot if not specified) to an existing animation +""" function frame{P<:AbstractPlot}(anim::Animation, plt::P=current()) i = length(anim.frames) + 1 filename = @sprintf("%06d.png", i) @@ -81,7 +86,7 @@ function buildanimation(animdir::AbstractString, fn::AbstractString; catch err warn("""Tried to create gif using convert (ImageMagick), but got error: $err ImageMagick can be installed by executing `Pkg.add("ImageMagick")`. - You may also need to install the imagemagick c++ library through your operating system. + You may also need to install the imagemagick c++ library through your operating system. Will try ffmpeg, but it's lower quality...)""") # low quality diff --git a/src/components.jl b/src/components.jl index 0ffe6226..eba135c2 100644 --- a/src/components.jl +++ b/src/components.jl @@ -39,6 +39,7 @@ vertices(shape::Shape) = collect(zip(shape.x, shape.y)) #deprecated @deprecate shape_coords coords +"return the vertex points from a Shape or Segments object" function coords(shape::Shape) shape.x, shape.y end @@ -163,6 +164,7 @@ Shape(k::Symbol) = deepcopy(_shapes[k]) # uses the centroid calculation from https://en.wikipedia.org/wiki/Centroid#Centroid_of_polygon +"return the centroid of a Shape" function center(shape::Shape) x, y = coords(shape) n = length(x) @@ -196,6 +198,7 @@ function scale(shape::Shape, x::Real, y::Real = x, c = center(shape)) scale!(shapecopy, x, y, c) end +"translate a Shape in space" function translate!(shape::Shape, x::Real, y::Real = x) sx, sy = coords(shape) for i=1:length(sx) @@ -234,6 +237,7 @@ function rotate!(shape::Shape, Θ::Real, c = center(shape)) shape end +"rotate an object in space" function rotate(shape::Shape, Θ::Real, c = center(shape)) shapecopy = deepcopy(shape) rotate!(shapecopy, Θ, c) @@ -362,6 +366,11 @@ immutable Stroke style end +""" + stroke(args...; alpha = nothing) + +Define the properties of the stroke used in plotting lines +""" function stroke(args...; alpha = nothing) width = 1 color = :black @@ -609,6 +618,12 @@ immutable Arrow headwidth::Float64 end +""" + arrow(args...) + +Define arrowheads to apply to lines - args are `style` (`:open` or `:closed`), +`side` (`:head`, `:tail` or `:both`), `headlength` and `headwidth` +""" function arrow(args...) style = :simple side = :head @@ -664,7 +679,7 @@ immutable Formatted{T} end # ----------------------------------------------------------------------- - +"create a BezierCurve for plotting" type BezierCurve{T <: FixedSizeArrays.Vec} control_points::Vector{T} end diff --git a/src/examples.jl b/src/examples.jl index 87ae1ca4..8ae108ef 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -360,6 +360,13 @@ function test_examples(pkgname::Symbol, idx::Int; debug = false, disp = true) end # generate all plots and create a dict mapping idx --> plt +""" +test_examples(pkgname[, idx]; debug = false, disp = true, sleep = nothing, + skip = [], only = nothing + +Run the `idx` test example for a given backend, or all examples if `idx` +is not specified. +""" function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = nothing, skip = [], only = nothing) Plots._debugMode.on = debug diff --git a/src/plotattr.jl b/src/plotattr.jl index cc8d053b..7313b2ce 100644 --- a/src/plotattr.jl +++ b/src/plotattr.jl @@ -14,6 +14,12 @@ function lookup_aliases(attrtype, attribute) error("There is no attribute named $attribute in $attrtype") end +""" + plotattr([attr]) + +Look up the properties of a Plots attribute, or specify an attribute type. Call `plotattr()` for options. +The information is the same as that given on https://juliaplots.github.io/attributes/. +""" function plotattr() println("Specify an attribute type to get a list of supported attributes. Options are $(attrtypes())") end diff --git a/src/recipes.jl b/src/recipes.jl index f5cb9b73..393bc2d4 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -847,6 +847,7 @@ end # TODO: move OHLC to PlotRecipes finance.jl +"Represent Open High Low Close data (used in finance)" type OHLC{T<:Real} open::T high::T diff --git a/src/utils.jl b/src/utils.jl index 6add802a..7e67f877 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -137,7 +137,7 @@ function imageHack(d::KW) end # --------------------------------------------------------------- - +"Build line segments for plotting" type Segments{T} pts::Vector{T} end @@ -185,6 +185,7 @@ type SegmentsIterator args::Tuple n::Int end + function iter_segments(args...) tup = Plots.wraptuple(args) n = maximum(map(length, tup)) From eea30fa2530ccba74c995579a8f6aa8e47b6ceb2 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Sat, 19 Aug 2017 10:34:06 +0100 Subject: [PATCH 277/720] added ribbon to plotly --- src/backends/plotly.jl | 26 +++++++++++++++++++------- src/utils.jl | 8 ++++++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9e0537ce..232a886e 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -438,7 +438,8 @@ function plotly_series(plt::Plot, series::Series) isscatter = st in (:scatter, :scatter3d, :scattergl) hasmarker = isscatter || series[:markershape] != :none hasline = st in (:path, :path3d) - hasfillrange = st in (:path, :scatter, :scattergl) && isa(series[:fillrange], AbstractVector) + hasfillrange = st in (:path, :scatter, :scattergl) && + (isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple)) # for surface types, set the data if st in (:heatmap, :contour, :surface, :wireframe) @@ -462,7 +463,7 @@ function plotly_series(plt::Plot, series::Series) else hasline ? "lines" : "none" end - if series[:fillrange] == true || series[:fillrange] == 0 + if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple) d_out[:fill] = "tozeroy" d_out[:fillcolor] = rgba_string(series[:fillcolor]) elseif isa(series[:fillrange], AbstractVector) @@ -587,11 +588,22 @@ function plotly_series(plt::Plot, series::Series) if hasfillrange # if hasfillrange is true, return two dictionaries (one for original # series, one for series being filled to) instead of one - d_out_fillrange = copy(d_out) - d_out_fillrange[:y] = series[:fillrange] - d_out_fillrange[:showlegend] = false - delete!(d_out_fillrange, :fill) - delete!(d_out_fillrange, :fillcolor) + d_out_fillrange = deepcopy(d_out) + if isa(series[:fillrange], AbstractVector) + d_out_fillrange[:y] = series[:fillrange] + d_out_fillrange[:showlegend] = false + delete!(d_out_fillrange, :fill) + delete!(d_out_fillrange, :fillcolor) + else + # if fillrange is a tuple with upper and lower limit, d_out_fillrange + # is the series that will do the filling + d_out_fillrange[:x], d_out_fillrange[:y] = + concatenate_fillrange(series[:x], series[:fillrange]) + d_out_fillrange[:line][:width] = 0 + d_out[:showlegend] = false + delete!(d_out, :fill) + delete!(d_out, :fillcolor) + end return [d_out_fillrange, d_out] else diff --git a/src/utils.jl b/src/utils.jl index 7e67f877..d3a9849c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -498,6 +498,14 @@ function make_fillrange_from_ribbon(kw::KW) kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2) end +#turn tuple of fillranges to one path +function concatenate_fillrange(x,y::Tuple) + rib1, rib2 = first(y), last(y) + yline = vcat(rib1,(rib2)[end:-1:1]) + xline = vcat(x,x[end:-1:1]) + return xline, yline +end + function get_sp_lims(sp::Subplot, letter::Symbol) axis_limits(sp[Symbol(letter, :axis)]) end From db3dca1d73ea8d046177b8126ae0bda127346302 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Sun, 20 Aug 2017 11:46:21 +0100 Subject: [PATCH 278/720] changed ribbon legend to line --- src/backends/plotly.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 232a886e..1bd9f096 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -589,9 +589,9 @@ function plotly_series(plt::Plot, series::Series) # if hasfillrange is true, return two dictionaries (one for original # series, one for series being filled to) instead of one d_out_fillrange = deepcopy(d_out) + d_out_fillrange[:showlegend] = false if isa(series[:fillrange], AbstractVector) d_out_fillrange[:y] = series[:fillrange] - d_out_fillrange[:showlegend] = false delete!(d_out_fillrange, :fill) delete!(d_out_fillrange, :fillcolor) else @@ -600,7 +600,6 @@ function plotly_series(plt::Plot, series::Series) d_out_fillrange[:x], d_out_fillrange[:y] = concatenate_fillrange(series[:x], series[:fillrange]) d_out_fillrange[:line][:width] = 0 - d_out[:showlegend] = false delete!(d_out, :fill) delete!(d_out, :fillcolor) end From e164ea4b463cf199a83b2bfcdd627c23d42e125c Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Sun, 20 Aug 2017 14:06:15 +0100 Subject: [PATCH 279/720] added default transparency to ribbon --- src/backends/gr.jl | 2 +- src/utils.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c2bf46ef..3622402b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1096,7 +1096,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) st = series[:seriestype] gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - if st == :shape || series[:fillrange] != nothing + if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) l, r = xpos-0.07, xpos-0.01 b, t = ypos-0.4dy, ypos+0.4dy diff --git a/src/utils.jl b/src/utils.jl index d3a9849c..8c5986fc 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -496,6 +496,7 @@ function make_fillrange_from_ribbon(kw::KW) rib1, rib2 = -first(rib), last(rib) # kw[:ribbon] = nothing kw[:fillrange] = make_fillrange_side(y, rib1), make_fillrange_side(y, rib2) + (get(kw, :fillalpha, nothing) == nothing) && (kw[:fillalpha] = 0.5) end #turn tuple of fillranges to one path From d76a6d1c38afb96be113e05c5797cf7c4660f7b2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 20 Aug 2017 15:43:52 +0200 Subject: [PATCH 280/720] Allow and as ticks --- src/axes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 734f2154..2bef9b4b 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -216,7 +216,7 @@ end # return (continuous_values, discrete_values) for the ticks on this axis function get_ticks(axis::Axis) - ticks = axis[:ticks] + ticks = _transform_ticks(axis[:ticks]) ticks in (nothing, false) && return nothing dvals = axis[:discrete_values] @@ -246,6 +246,10 @@ function get_ticks(axis::Axis) end end +_transform_ticks(ticks) = ticks +_transform_ticks(ticks::AbstractArray{T}) where T <: Dates.TimeType = Dates.value.(ticks) +_transform_ticks(ticks::NTuple{2, Any}) = (_transform_ticks(ticks[1]), ticks[2]) + # ------------------------------------------------------------------------- From be4a3741224afc04d64c805a845d762ca64f2a69 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 20 Aug 2017 21:55:21 +0200 Subject: [PATCH 281/720] allow turning on/off the axes border --- src/arg_desc.jl | 1 + src/args.jl | 2 ++ src/axes.jl | 8 ++++---- src/backends/glvisualize.jl | 3 ++- src/backends/gr.jl | 1 + src/backends/pyplot.jl | 7 +++++++ 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index ee1e99d8..f3b56493 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -93,6 +93,7 @@ const _arg_desc = KW( :bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.", :subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.", :colorbar_title => "String. Title of colorbar.", +:draw_axes_border => "Bool. Draw a border around the axes.", # axis args :guide => "String. Axis guide (label).", diff --git a/src/args.jl b/src/args.jl index 37dd250e..4665f964 100644 --- a/src/args.jl +++ b/src/args.jl @@ -282,6 +282,7 @@ const _subplot_defaults = KW( :bottom_margin => :match, :subplot_index => -1, :colorbar_title => "", + :draw_axes_border => false, ) const _axis_defaults = KW( @@ -493,6 +494,7 @@ add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) +add_aliases(:draw_axes_border, :axes_border, :show_axes_border) # add all pluralized forms to the _keyAliases dict diff --git a/src/axes.jl b/src/axes.jl index 734f2154..22c868ff 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -502,10 +502,10 @@ function axis_drawing_info(sp::Subplot) t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) push!(xspine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine - # push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine + sp[:draw_axes_border] && push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine for xtick in xticks[1] push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick - # push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick + # sp[:draw_axes_border] && push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end end @@ -517,10 +517,10 @@ function axis_drawing_info(sp::Subplot) t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) push!(yspine_segs, (xmin,ymin), (xmin,ymax)) # left spine - # push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine + sp[:draw_axes_border] && push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine for ytick in yticks[1] push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick - # push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick + # sp[:draw_axes_border] && push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 60c1730a..91deb56c 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -39,7 +39,8 @@ const _glvisualize_attr = merge_with_base_supported([ :clims, :inset_subplots, :dpi, - :hover + :hover, + :draw_axes_border, ]) const _glvisualize_seriestype = [ :path, :shape, diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 3622402b..0c01b8f4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -32,6 +32,7 @@ const _gr_attr = merge_with_base_supported([ :inset_subplots, :bar_width, :arrow, + :draw_axes_border, ]) const _gr_seriestype = [ :path, :scatter, diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 4b185e6e..ea143e1e 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -32,6 +32,7 @@ const _pyplot_attr = merge_with_base_supported([ :inset_subplots, :dpi, :colorbar_title, + :draw_axes_border, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -1088,6 +1089,12 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # this sets the bg color inside the grid ax[set_facecolor_sym](py_color(sp[:background_color_inside])) + + if !sp[:draw_axes_border] + # hide the right and top spines + ax[:spines]["right"][:set_visible](false) + ax[:spines]["top"][:set_visible](false) + end end py_drawfig(fig) end From be8c66adc9da0d5c79743863ad9f3f5f2fc6d99e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 20 Aug 2017 22:45:30 +0200 Subject: [PATCH 282/720] fix polar plots on pyplot --- src/backends/pyplot.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ea143e1e..5e4d4c82 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1091,9 +1091,15 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ax[set_facecolor_sym](py_color(sp[:background_color_inside])) if !sp[:draw_axes_border] - # hide the right and top spines - ax[:spines]["right"][:set_visible](false) - ax[:spines]["top"][:set_visible](false) + if ispolar(sp) + for (loc, spine) in ax[:spines] + spine[:set_visible](false) + end + else + # hide the right and top spines + ax[:spines]["right"][:set_visible](false) + ax[:spines]["top"][:set_visible](false) + end end end py_drawfig(fig) From 113751323678bcfadaf4741866e33ecfe9e51ac5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 21 Aug 2017 00:07:44 +0200 Subject: [PATCH 283/720] add aliases :box and :frame --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 4665f964..5daf08e8 100644 --- a/src/args.jl +++ b/src/args.jl @@ -494,7 +494,7 @@ add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) -add_aliases(:draw_axes_border, :axes_border, :show_axes_border) +add_aliases(:draw_axes_border, :axes_border, :show_axes_border, :box, :frame) # add all pluralized forms to the _keyAliases dict From 25774ee4c3ff86e706ec0dd5b8e9ae6ba81498e9 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 21 Aug 2017 10:19:47 +0200 Subject: [PATCH 284/720] Turn off gui for pyplot in ijulia --- src/output.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/output.jl b/src/output.jl index 14f15c30..41cc9d0c 100644 --- a/src/output.jl +++ b/src/output.jl @@ -278,6 +278,7 @@ using Requires show(io, MIME("text/html"), plt) end + ENV["MPLBACKEND"] = "Agg" set_ijulia_output("text/html") end end From 9529246bfb20eaf8101fe7a9e7f671c04c0fc7be Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 21 Aug 2017 14:30:44 +0100 Subject: [PATCH 285/720] keywords arguments of same length as series get grouped --- src/args.jl | 2 +- src/series.jl | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 37dd250e..ef403a04 100644 --- a/src/args.jl +++ b/src/args.jl @@ -854,7 +854,7 @@ end # expecting a mapping of "group label" to "group indices" function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...) groupLabels = sortedkeys(idxmap) - groupIds = VecI[collect(idxmap[k]) for k in groupLabels] + groupIds = Vector{Int}[collect(idxmap[k]) for k in groupLabels] GroupBy(groupLabels, groupIds) end diff --git a/src/series.jl b/src/series.jl index ca520168..746e206d 100644 --- a/src/series.jl +++ b/src/series.jl @@ -515,6 +515,13 @@ end @series begin label --> string(glab) idxfilter --> groupby.groupIds[i] + for (key,val) in d + length(args) == 0 && break + if key != :group && isa(val, AbstractArray) && size(val,1) == size(args[1],1) + n = ndims(val) + :($key) := val[groupby.groupIds[i], fill(Colon(), n-1)...] + end + end args end end From 6dba32bf9989fbb3713d4da661984b773af878d5 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 21 Aug 2017 15:53:31 +0100 Subject: [PATCH 286/720] only check kw is at least as long as group --- src/series.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index 746e206d..f4f277a8 100644 --- a/src/series.jl +++ b/src/series.jl @@ -511,13 +511,13 @@ end # split the group into 1 series per group, and set the label and idxfilter for each @recipe function f(groupby::GroupBy, args...) + lengthGroup = maximum(union(groupby.groupIds...)) for (i,glab) in enumerate(groupby.groupLabels) @series begin label --> string(glab) idxfilter --> groupby.groupIds[i] for (key,val) in d - length(args) == 0 && break - if key != :group && isa(val, AbstractArray) && size(val,1) == size(args[1],1) + if key != :group && isa(val, AbstractArray) && size(val,1) >= lengthGroup n = ndims(val) :($key) := val[groupby.groupIds[i], fill(Colon(), n-1)...] end From 34f9cfaa0211e6fb0c7483c6e5a4f4f4d96b28c1 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Wed, 23 Aug 2017 00:27:33 -0700 Subject: [PATCH 287/720] Remove the -pre Plots.jl is no longer tested on the prereleases so it shouldn't say that they are supported. --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 6b96e23e..888aaf7d 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,4 +1,4 @@ -julia 0.6-pre +julia 0.6 RecipesBase 0.2.0 PlotUtils 0.4.1 From f751b1b7ff901d86402ea1ac1bb1167d52b393be Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 23 Aug 2017 01:45:54 +0100 Subject: [PATCH 288/720] don't draw fill for 1D markers in gr --- src/backends/gr.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 3622402b..c90c26b8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -326,7 +326,10 @@ function gr_draw_markers(series::Series, x, y, msize, mz) cfuncind(ci) GR.settransparency(_gr_gradient_alpha[ci-999]) end - gr_draw_marker(x[i], y[i], msi, shape) + # don't draw filled area if marker shape is 1D + if !(shape in (:hline, :vline, :+, :x, :cross, :xcross)) + gr_draw_marker(x[i], y[i], msi, shape) + end end end end From e16125cb507438c9399d1ea499933ca46ecf474f Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 23 Aug 2017 13:49:33 +0100 Subject: [PATCH 289/720] some GR margin fixes --- src/backends/gr.jl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c90c26b8..d1924446 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -326,7 +326,7 @@ function gr_draw_markers(series::Series, x, y, msize, mz) cfuncind(ci) GR.settransparency(_gr_gradient_alpha[ci-999]) end - # don't draw filled area if marker shape is 1D + # don't draw filled area if marker shape is 1D if !(shape in (:hline, :vline, :+, :x, :cross, :xcross)) gr_draw_marker(x[i], y[i], msi, shape) end @@ -543,10 +543,10 @@ end function _update_min_padding!(sp::Subplot{GRBackend}) - leftpad = 10mm - toppad = 2mm - rightpad = 2mm - bottompad = 6mm + leftpad = 10mm + sp[:left_margin] + toppad = 2mm + sp[:top_margin] + rightpad = 2mm + sp[:right_margin] + bottompad = 6mm + sp[:bottom_margin] if sp[:title] != "" toppad += 5mm end @@ -558,10 +558,11 @@ function _update_min_padding!(sp::Subplot{GRBackend}) valign = :top, color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) - h = 0 + h = 0.0 for (cv, dv) in zip(xticks...) tbx, tby = gr_inqtext(0, 0, string(dv)) - h = max(h, tby[2] - tby[1]) + tby_min, tby_max = extrema(tby) + h = max(h, tby_max - tby_min) end bottompad += 1mm + gr_plot_size[2] * h * px else From b3b533db94c58b1dc666bb6722cbc9426141028b Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 23 Aug 2017 14:10:35 +0100 Subject: [PATCH 290/720] fix margin in case there is no label (gr) --- src/backends/gr.jl | 42 +++++++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d1924446..4a3c06ee 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -543,32 +543,36 @@ end function _update_min_padding!(sp::Subplot{GRBackend}) + # Add margin given by the user leftpad = 10mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] - rightpad = 2mm + sp[:right_margin] - bottompad = 6mm + sp[:bottom_margin] + rightpad = 4mm + sp[:right_margin] + bottompad = 2mm + sp[:bottom_margin] + # Add margin for title if sp[:title] != "" toppad += 5mm end - if sp[:xaxis][:guide] != "" - xticks = axis_drawing_info(sp)[1] - if !(xticks in (nothing, false)) - gr_set_font(sp[:xaxis][:tickfont], - halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], - valign = :top, - color = sp[:xaxis][:foreground_color_axis], - rotation = sp[:xaxis][:rotation]) - h = 0.0 - for (cv, dv) in zip(xticks...) - tbx, tby = gr_inqtext(0, 0, string(dv)) - tby_min, tby_max = extrema(tby) - h = max(h, tby_max - tby_min) - end - bottompad += 1mm + gr_plot_size[2] * h * px - else - bottompad += 4mm + # Add margin for x ticks + xticks = axis_drawing_info(sp)[1] + if !(xticks in (nothing, false)) + gr_set_font(sp[:xaxis][:tickfont], + halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], + valign = :top, + color = sp[:xaxis][:foreground_color_axis], + rotation = sp[:xaxis][:rotation]) + h = 0.0 + for (cv, dv) in zip(xticks...) + tbx, tby = gr_inqtext(0, 0, string(dv)) + tby_min, tby_max = extrema(tby) + h = max(h, tby_max - tby_min) end + bottompad += 1mm + gr_plot_size[2] * h * px end + # Add margin for x label + if sp[:xaxis][:guide] != "" + bottompad += 4mm + end + # Add margin for y label if sp[:yaxis][:guide] != "" leftpad += 4mm end From 06115f25bad8114c187f4b32a013b55236ae46ec Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 23 Aug 2017 17:43:06 +0100 Subject: [PATCH 291/720] factorize tickfont --- src/backends/gr.jl | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 4a3c06ee..12fd42de 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -542,6 +542,30 @@ function gr_display(plt::Plot) end +function gr_set_xticks_font(sp) + flip = sp[:yaxis][:flip] + mirror = sp[:xaxis][:mirror] + gr_set_font(sp[:xaxis][:tickfont], + halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], + valign = (mirror ? :bottom : :top), + color = sp[:xaxis][:foreground_color_axis], + rotation = sp[:xaxis][:rotation]) + return flip, mirror +end + + +function gr_set_yticks_font(sp) + flip = sp[:xaxis][:flip] + mirror = sp[:yaxis][:mirror] + gr_set_font(sp[:yaxis][:tickfont], + halign = (mirror ? :left : :right), + valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2], + color = sp[:yaxis][:foreground_color_axis], + rotation = sp[:yaxis][:rotation]) + return flip, mirror +end + + function _update_min_padding!(sp::Subplot{GRBackend}) # Add margin given by the user leftpad = 10mm + sp[:left_margin] @@ -747,13 +771,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if !(xticks in (nothing, false)) # x labels - flip = sp[:yaxis][:flip] - mirror = sp[:xaxis][:mirror] - gr_set_font(sp[:xaxis][:tickfont], - halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], - valign = (mirror ? :bottom : :top), - color = sp[:xaxis][:foreground_color_axis], - rotation = sp[:xaxis][:rotation]) + flip, mirror = gr_set_xticks_font(sp) for (cv, dv) in zip(xticks...) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, xor(flip, mirror) ? ymax : ymin) @@ -764,13 +782,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if !(yticks in (nothing, false)) # y labels - flip = sp[:xaxis][:flip] - mirror = sp[:yaxis][:mirror] - gr_set_font(sp[:yaxis][:tickfont], - halign = (mirror ? :left : :right), - valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2], - color = sp[:yaxis][:foreground_color_axis], - rotation = sp[:yaxis][:rotation]) + flip, mirror = gr_set_yticks_font(sp) for (cv, dv) in zip(yticks...) # use xor ($) to get the right y coords xi, yi = GR.wctondc(xor(flip, mirror) ? xmax : xmin, cv) From 91158b1c20708375082301d9a272c33b3b135157 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 23 Aug 2017 18:00:39 +0100 Subject: [PATCH 292/720] add proper pad for ticks --- src/backends/gr.jl | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 12fd42de..515aaa7e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -565,10 +565,19 @@ function gr_set_yticks_font(sp) return flip, mirror end +function gr_get_ticks_size(ticks, i) + l = 0.0 + for (cv, dv) in zip(ticks...) + tb = gr_inqtext(0, 0, string(dv))[i] + tb_min, tb_max = extrema(tb) + l = max(l, tb_max - tb_min) + end + return l +end function _update_min_padding!(sp::Subplot{GRBackend}) # Add margin given by the user - leftpad = 10mm + sp[:left_margin] + leftpad = 2mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] rightpad = 4mm + sp[:right_margin] bottompad = 2mm + sp[:bottom_margin] @@ -576,21 +585,25 @@ function _update_min_padding!(sp::Subplot{GRBackend}) if sp[:title] != "" toppad += 5mm end - # Add margin for x ticks - xticks = axis_drawing_info(sp)[1] + # Add margin for x and y ticks + xticks, yticks = axis_drawing_info(sp)[1:2] if !(xticks in (nothing, false)) - gr_set_font(sp[:xaxis][:tickfont], - halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], - valign = :top, - color = sp[:xaxis][:foreground_color_axis], - rotation = sp[:xaxis][:rotation]) - h = 0.0 - for (cv, dv) in zip(xticks...) - tbx, tby = gr_inqtext(0, 0, string(dv)) - tby_min, tby_max = extrema(tby) - h = max(h, tby_max - tby_min) + flip, mirror = gr_set_xticks_font(sp) + l = gr_get_ticks_size(xticks, 2) + if mirror + toppad += 1mm + gr_plot_size[2] * l * px + else + bottompad += 1mm + gr_plot_size[2] * l * px + end + end + if !(yticks in (nothing, false)) + flip, mirror = gr_set_yticks_font(sp) + l = gr_get_ticks_size(yticks, 1) + if mirror + rightpad += 1mm + gr_plot_size[1] * l * px + else + leftpad += 1mm + gr_plot_size[1] * l * px end - bottompad += 1mm + gr_plot_size[2] * h * px end # Add margin for x label if sp[:xaxis][:guide] != "" From 5a2d39320f3cc499fd0b297886f96fe6e956e2d3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 16:13:01 +0200 Subject: [PATCH 293/720] framestyle attribute for gr, pyplot and glvisualize --- src/arg_desc.jl | 2 +- src/args.jl | 18 ++++++++++++++-- src/axes.jl | 42 +++++++++++++++++++++---------------- src/backends/glvisualize.jl | 13 ++++++++++-- src/backends/gr.jl | 20 ++++++++++++++---- src/backends/pyplot.jl | 36 +++++++++++++++++++++++-------- 6 files changed, 95 insertions(+), 36 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f3b56493..2aad42a5 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -93,7 +93,7 @@ const _arg_desc = KW( :bottom_margin => "Measure (multiply by `mm`, `px`, etc) or `:match` (matches `:margin`). Specifies the extra padding on the bottom of the subplot.", :subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.", :colorbar_title => "String. Title of colorbar.", -:draw_axes_border => "Bool. Draw a border around the axes.", +:framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)", # axis args :guide => "String. Axis guide (label).", diff --git a/src/args.jl b/src/args.jl index 5daf08e8..bc9ce5af 100644 --- a/src/args.jl +++ b/src/args.jl @@ -181,6 +181,14 @@ function hasgrid(arg::Symbol, letter) end hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) +const _allFramestyles = [:box, :semi, :axes, :grid, :none] +const _framestyleAliases = Dict{Symbol, Symbol}( + :frame => :box, + :border => :box, + :on => :box, + :transparent => :semi, + :semitransparent => :semi, +) # ----------------------------------------------------------------------------- const _series_defaults = KW( @@ -282,7 +290,7 @@ const _subplot_defaults = KW( :bottom_margin => :match, :subplot_index => -1, :colorbar_title => "", - :draw_axes_border => false, + :framestyle => :axes, ) const _axis_defaults = KW( @@ -494,7 +502,7 @@ add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) -add_aliases(:draw_axes_border, :axes_border, :show_axes_border, :box, :frame) +add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box) # add all pluralized forms to the _keyAliases dict @@ -721,6 +729,7 @@ function preprocessArgs!(d::KW) if haskey(d, :axis) && d[:axis] in (:none, nothing, false) d[:ticks] = nothing d[:foreground_color_border] = RGBA(0,0,0,0) + d[:foreground_color_axis] = RGBA(0,0,0,0) d[:grid] = false delete!(d, :axis) end @@ -823,6 +832,11 @@ function preprocessArgs!(d::KW) d[:colorbar] = convertLegendValue(d[:colorbar]) end + + if haskey(d, :framestyle) && haskey(_framestyleAliases, d[:framestyle]) + d[:framestyle] = _framestyleAliases[d[:framestyle]] + end + # warnings for moved recipes st = get(d, :seriestype, :path) if st in (:boxplot, :violin, :density) && !isdefined(Main, :StatPlots) diff --git a/src/axes.jl b/src/axes.jl index 22c868ff..6b3962a6 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -490,40 +490,46 @@ function axis_drawing_info(sp::Subplot) ymin, ymax = axis_limits(yaxis) xticks = get_ticks(xaxis) yticks = get_ticks(yaxis) - xspine_segs = Segments(2) - yspine_segs = Segments(2) + xaxis_segs = Segments(2) + yaxis_segs = Segments(2) xgrid_segs = Segments(2) ygrid_segs = Segments(2) + xborder_segs = Segments(2) + yborder_segs = Segments(2) - if !(xaxis[:ticks] in (nothing, false)) + if !(sp[:framestyle] == :none) + # xaxis f = scalefunc(yaxis[:scale]) invf = invscalefunc(yaxis[:scale]) t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - push!(xspine_segs, (xmin,ymin), (xmax,ymin)) # bottom spine - sp[:draw_axes_border] && push!(xspine_segs, (xmin,ymax), (xmax,ymax)) # top spine - for xtick in xticks[1] - push!(xspine_segs, (xtick, ymin), (xtick, t1)) # bottom tick - # sp[:draw_axes_border] && push!(xspine_segs, (xtick, ymax), (xtick, t2)) # top tick - xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + sp[:framestyle] == :grid || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine + if !(xaxis[:ticks] in (nothing, false)) + for xtick in xticks[1] + push!(xaxis_segs, (xtick, ymin), (xtick, t1)) # bottom tick + # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick + xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + end end - end - if !(yaxis[:ticks] in (nothing, false)) + # yaxis f = scalefunc(xaxis[:scale]) invf = invscalefunc(xaxis[:scale]) t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - push!(yspine_segs, (xmin,ymin), (xmin,ymax)) # left spine - sp[:draw_axes_border] && push!(yspine_segs, (xmax,ymin), (xmax,ymax)) # right spine - for ytick in yticks[1] - push!(yspine_segs, (xmin, ytick), (t1, ytick)) # left tick - # sp[:draw_axes_border] && push!(yspine_segs, (xmax, ytick), (t2, ytick)) # right tick - yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + sp[:framestyle] == :grid || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine + if !(yaxis[:ticks] in (nothing, false)) + for ytick in yticks[1] + push!(yaxis_segs, (xmin, ytick), (t1, ytick)) # left tick + # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick + yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + end end end - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs + xticks, yticks, xaxis_segs, yaxis_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 91deb56c..1d4fc017 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -40,7 +40,7 @@ const _glvisualize_attr = merge_with_base_supported([ :inset_subplots, :dpi, :hover, - :draw_axes_border, + :framestyle, ]) const _glvisualize_seriestype = [ :path, :shape, @@ -678,7 +678,7 @@ function text_model(font, pivot) end end function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area) - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = Plots.axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp) xaxis = sp[:xaxis]; yaxis = sp[:yaxis] xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid])) @@ -728,6 +728,15 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) end + xbc = Colors.color(Plots.gl_color(xaxis[:foreground_color_border])) + ybc = Colors.color(Plots.gl_color(yaxis[:foreground_color_border])) + intensity = sp[:framestyle] == :semi ? 0.5f0 : 1.0f0 + if sp[:framestyle] in (:box, :semi) + xborder = draw_grid_lines(sp, xborder_segs, intensity, :solid, model, RGBA(xbc, intensity)) + yborder = draw_grid_lines(sp, yborder_segs, intensity, :solid, model, RGBA(ybc, intensity)) + push!(axis_vis, xborder, yborder) + end + area_w = GeometryTypes.widths(area) if sp[:title] != "" tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title]) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0c01b8f4..60e7df00 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -32,7 +32,7 @@ const _gr_attr = merge_with_base_supported([ :inset_subplots, :bar_width, :arrow, - :draw_axes_border, + :framestyle, ]) const _gr_seriestype = [ :path, :scatter, @@ -609,7 +609,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # TODO: can these be generic flags? outside_ticks = false cmap = false - draw_axes = true + draw_axes = sp[:framestyle] != :none # axes_2d = true for series in series_list(sp) st = series[:seriestype] @@ -711,7 +711,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setwindow(xmin, xmax, ymin, ymax) end - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs = axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp) # @show xticks yticks #spine_segs grid_segs # draw the grid lines @@ -729,7 +729,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end GR.settransparency(1.0) - # spine (border) and tick marks + # axis lines gr_set_line(1, :solid, xaxis[:foreground_color_axis]) GR.setclip(0) gr_polyline(coords(xspine_segs)...) @@ -738,6 +738,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_polyline(coords(yspine_segs)...) GR.setclip(1) + # tick marks if !(xticks in (nothing, false)) # x labels flip = sp[:yaxis][:flip] @@ -771,6 +772,17 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) end end + + # border + intensity = sp[:framestyle] == :semi ? 0.5 : 1.0 + if sp[:framestyle] in (:box, :semi) + gr_set_line(intensity, :solid, xaxis[:foreground_color_border]) + GR.settransparency(intensity) + gr_polyline(coords(xborder_segs)...) + gr_set_line(intensity, :solid, yaxis[:foreground_color_border]) + GR.settransparency(intensity) + gr_polyline(coords(yborder_segs)...) + end end # end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 5e4d4c82..5db0ba6b 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -32,7 +32,7 @@ const _pyplot_attr = merge_with_base_supported([ :inset_subplots, :dpi, :colorbar_title, - :draw_axes_border, + :framestyle, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -1054,7 +1054,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end py_set_scale(ax, axis) py_set_lims(ax, axis) - py_set_ticks(ax, get_ticks(axis), letter) + ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis) + py_set_ticks(ax, ticks, letter) ax[Symbol("set_", letter, "label")](axis[:guide]) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() @@ -1066,7 +1067,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) lab[:set_family](axis[:tickfont].family) lab[:set_rotation](axis[:rotation]) end - if axis[:grid] + if axis[:grid] && sp[:framestyle] != :none fgcolor = py_color(axis[:foreground_color_grid]) pyaxis[:grid](true, color = fgcolor, @@ -1090,17 +1091,34 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # this sets the bg color inside the grid ax[set_facecolor_sym](py_color(sp[:background_color_inside])) - if !sp[:draw_axes_border] - if ispolar(sp) + # framestyle + if !ispolar(sp) && !is3d(sp) + if sp[:framestyle] == :semi + intensity = 0.5 + ax[:spines]["right"][:set_alpha](intensity) + ax[:spines]["top"][:set_alpha](intensity) + ax[:spines]["right"][:set_linewidth](intensity) + ax[:spines]["top"][:set_linewidth](intensity) + elseif sp[:framestyle] == :axes + ax[:spines]["right"][:set_visible](false) + ax[:spines]["top"][:set_visible](false) + elseif sp[:framestyle] in (:grid, :none) for (loc, spine) in ax[:spines] spine[:set_visible](false) end - else - # hide the right and top spines - ax[:spines]["right"][:set_visible](false) - ax[:spines]["top"][:set_visible](false) end end + # if !sp[:draw_axes_border] + # if ispolar(sp) + # for (loc, spine) in ax[:spines] + # spine[:set_visible](false) + # end + # else + # # hide the right and top spines + # ax[:spines]["right"][:set_visible](false) + # ax[:spines]["top"][:set_visible](false) + # end + # end end py_drawfig(fig) end From 2bbd4cbb17922ad035533bdf8857ff610a288823 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 16:26:54 +0200 Subject: [PATCH 294/720] clean up --- src/args.jl | 2 +- src/axes.jl | 20 ++++++++++---------- src/backends/pyplot.jl | 11 ----------- 3 files changed, 11 insertions(+), 22 deletions(-) diff --git a/src/args.jl b/src/args.jl index bc9ce5af..0b5750ab 100644 --- a/src/args.jl +++ b/src/args.jl @@ -832,7 +832,7 @@ function preprocessArgs!(d::KW) d[:colorbar] = convertLegendValue(d[:colorbar]) end - + # framestyle if haskey(d, :framestyle) && haskey(_framestyleAliases, d[:framestyle]) d[:framestyle] = _framestyleAliases[d[:framestyle]] end diff --git a/src/axes.jl b/src/axes.jl index 6b3962a6..72745d86 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -499,14 +499,14 @@ function axis_drawing_info(sp::Subplot) if !(sp[:framestyle] == :none) # xaxis - f = scalefunc(yaxis[:scale]) - invf = invscalefunc(yaxis[:scale]) - t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) - t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - sp[:framestyle] == :grid || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine if !(xaxis[:ticks] in (nothing, false)) + f = scalefunc(yaxis[:scale]) + invf = invscalefunc(yaxis[:scale]) + t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) + t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) + for xtick in xticks[1] push!(xaxis_segs, (xtick, ymin), (xtick, t1)) # bottom tick # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick @@ -515,14 +515,14 @@ function axis_drawing_info(sp::Subplot) end # yaxis - f = scalefunc(xaxis[:scale]) - invf = invscalefunc(xaxis[:scale]) - t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) - t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - sp[:framestyle] == :grid || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine if !(yaxis[:ticks] in (nothing, false)) + f = scalefunc(xaxis[:scale]) + invf = invscalefunc(xaxis[:scale]) + t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) + t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) + for ytick in yticks[1] push!(yaxis_segs, (xmin, ytick), (t1, ytick)) # left tick # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 5db0ba6b..03c047bf 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1108,17 +1108,6 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end end end - # if !sp[:draw_axes_border] - # if ispolar(sp) - # for (loc, spine) in ax[:spines] - # spine[:set_visible](false) - # end - # else - # # hide the right and top spines - # ax[:spines]["right"][:set_visible](false) - # ax[:spines]["top"][:set_visible](false) - # end - # end end py_drawfig(fig) end From d301d2a06b12fa2156ddfe01caa7b58014cc9232 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 16:58:43 +0200 Subject: [PATCH 295/720] fix ticks = nothing on pyplot, ... --- src/args.jl | 2 +- src/backends/gr.jl | 4 ++-- src/backends/pyplot.jl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/args.jl b/src/args.jl index 0b5750ab..f312675f 100644 --- a/src/args.jl +++ b/src/args.jl @@ -432,7 +432,7 @@ add_aliases(:foreground_color_title, :fg_title, :fgtitle, :fgcolor_title, :fg_co add_aliases(:foreground_color_axis, :fg_axis, :fgaxis, :fgcolor_axis, :fg_color_axis, :foreground_axis, :foreground_colour_axis, :fgcolour_axis, :fg_colour_axis, :axiscolor) add_aliases(:foreground_color_border, :fg_border, :fgborder, :fgcolor_border, :fg_color_border, :foreground_border, - :foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor, :border) + :foreground_colour_border, :fgcolour_border, :fg_colour_border, :bordercolor) add_aliases(:foreground_color_text, :fg_text, :fgtext, :fgcolor_text, :fg_color_text, :foreground_text, :foreground_colour_text, :fgcolour_text, :fg_colour_text, :textcolor) add_aliases(:foreground_color_guide, :fg_guide, :fgguide, :fgcolor_guide, :fg_color_guide, :foreground_guide, diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 60e7df00..563873b0 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -739,7 +739,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setclip(1) # tick marks - if !(xticks in (nothing, false)) + if !(xticks in (:none, nothing, false)) # x labels flip = sp[:yaxis][:flip] mirror = sp[:xaxis][:mirror] @@ -756,7 +756,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end end - if !(yticks in (nothing, false)) + if !(yticks in (:none, nothing, false)) # y labels flip = sp[:xaxis][:flip] mirror = sp[:yaxis][:mirror] diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 03c047bf..80a7f77c 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1067,7 +1067,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) lab[:set_family](axis[:tickfont].family) lab[:set_rotation](axis[:rotation]) end - if axis[:grid] && sp[:framestyle] != :none + if axis[:grid] && !(ticks in (:none, nothing, false)) fgcolor = py_color(axis[:foreground_color_grid]) pyaxis[:grid](true, color = fgcolor, From e2d107a70b215104d4e85f8c7ef657495066f25e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 21:39:33 +0200 Subject: [PATCH 296/720] add framestyle test example --- src/args.jl | 2 +- src/examples.jl | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/args.jl b/src/args.jl index f312675f..5f9e320d 100644 --- a/src/args.jl +++ b/src/args.jl @@ -502,7 +502,7 @@ add_aliases(:orientation, :direction, :dir) add_aliases(:inset_subplots, :inset, :floating) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) -add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box) +add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) # add all pluralized forms to the _keyAliases dict diff --git a/src/examples.jl b/src/examples.jl index 8ae108ef..d1775f47 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -155,7 +155,7 @@ PlotExample("Subplots", """, [:(begin l = @layout([a{0.1h}; b [c;d e]]) - plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, ticks=nothing, border=false) + plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, ticks=nothing, border=:none) end)] ), @@ -330,7 +330,7 @@ PlotExample("Spy", ), PlotExample("Magic grid argument", - "The grid lines can be modified individually for each axis with the magic grid argument.", + "The grid lines can be modified individually for each axis with the magic `grid` argument.", [:(begin x = rand(10) p1 = plot(x, title = "Default looks") @@ -341,6 +341,14 @@ PlotExample("Magic grid argument", end)] ), +PlotExample("Framestyle", + "The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`.", + [:(begin + histogram(fill(randn(1000), 5), framestyle = [:box :semi :axes :grid :none], + title = [":box" ":semi" ":axes" ":grid" ":none"], color = RowVector(1:5), layout = 5, label = "") + end)] +), + ] # --------------------------------------------------------------------------------- @@ -365,7 +373,7 @@ test_examples(pkgname[, idx]; debug = false, disp = true, sleep = nothing, skip = [], only = nothing Run the `idx` test example for a given backend, or all examples if `idx` -is not specified. +is not specified. """ function test_examples(pkgname::Symbol; debug = false, disp = true, sleep = nothing, skip = [], only = nothing) From a4ed700338a8b946d6b2c130a9386c24c014e27e Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Sat, 20 May 2017 15:44:48 -0700 Subject: [PATCH 297/720] Use `invokelatest` to get around world age issue --- src/pipeline.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index 8879ff6f..e0041b77 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -210,7 +210,7 @@ function _plot_setup(plt::Plot, d::KW, kw_list::Vector{KW}) # TODO: init subplots here _update_plot_args(plt, d) if !plt.init - plt.o = _create_backend_figure(plt) + plt.o = Base.invokelatest(_create_backend_figure, plt) # create the layout and subplots from the inputs plt.layout, plt.subplots, plt.spmap = build_layout(plt.attr) From 54adc343488131151337a1dc8c4acacb43230c62 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 24 Aug 2017 22:21:13 +0200 Subject: [PATCH 298/720] fix glvisualize framestyle :none ticks --- src/backends/glvisualize.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 1d4fc017..974b73b1 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -708,7 +708,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are xlim = Plots.axis_limits(xaxis) ylim = Plots.axis_limits(yaxis) - if !(xaxis[:ticks] in (nothing, false, :none)) + if !(xaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none) ticklabels = map(model) do m mirror = xaxis[:mirror] t, positions, offsets = draw_ticks(xaxis, xticks, true, ylim, m) From c0f274d54b2246fc7917c9dc7a1b54371286d7d4 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 24 Aug 2017 22:27:04 -0400 Subject: [PATCH 299/720] gr: always use NDCs when inquiring text extents --- src/backends/gr.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 092b00d3..43e55d4f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -567,12 +567,15 @@ function gr_set_yticks_font(sp) end function gr_get_ticks_size(ticks, i) + GR.savestate() + GR.selntran(0) l = 0.0 for (cv, dv) in zip(ticks...) tb = gr_inqtext(0, 0, string(dv))[i] tb_min, tb_max = extrema(tb) l = max(l, tb_max - tb_min) end + GR.restorestate() return l end From dbbbeddad0a5b877b94e618fc79827c5bbe7afea Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 24 Aug 2017 22:27:04 -0400 Subject: [PATCH 300/720] gr: always use NDCs when inquiring text extents --- src/backends/gr.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 092b00d3..43e55d4f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -567,12 +567,15 @@ function gr_set_yticks_font(sp) end function gr_get_ticks_size(ticks, i) + GR.savestate() + GR.selntran(0) l = 0.0 for (cv, dv) in zip(ticks...) tb = gr_inqtext(0, 0, string(dv))[i] tb_min, tb_max = extrema(tb) l = max(l, tb_max - tb_min) end + GR.restorestate() return l end From 6f3301e82ffdbf614d0ad44efcfb939dbf920f46 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 25 Aug 2017 14:16:53 +0200 Subject: [PATCH 301/720] make linecolor default to auto --- src/args.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index 5f9e320d..203db58f 100644 --- a/src/args.jl +++ b/src/args.jl @@ -198,7 +198,7 @@ const _series_defaults = KW( :seriestype => :path, :linestyle => :solid, :linewidth => :auto, - :linecolor => :match, + :linecolor => :auto, :linealpha => nothing, :fillrange => nothing, # ribbons, areas, etc :fillcolor => :match, @@ -1333,12 +1333,14 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) # update other colors for s in (:line, :marker, :fill) csym, asym = Symbol(s,:color), Symbol(s,:alpha) - d[csym] = if d[csym] == :match + d[csym] = if d[csym] == :auto plot_color(if has_black_border_for_default(d[:seriestype]) && s == :line sp[:foreground_color_subplot] else d[:seriescolor] end, d[asym]) + elseif d[csym] == :match + plot_color(d[:seriescolor], d[asym]) else getSeriesRGBColor(d[csym], d[asym], sp, plotIndex) end From 509f8f6a95fc21d993498fff993704c9fdcff48e Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Fri, 25 Aug 2017 16:46:07 +0100 Subject: [PATCH 302/720] readd fill for cross and xcross on GR --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 43e55d4f..de1e579e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -328,7 +328,7 @@ function gr_draw_markers(series::Series, x, y, msize, mz) GR.settransparency(_gr_gradient_alpha[ci-999]) end # don't draw filled area if marker shape is 1D - if !(shape in (:hline, :vline, :+, :x, :cross, :xcross)) + if !(shape in (:hline, :vline, :+, :x)) gr_draw_marker(x[i], y[i], msi, shape) end end From 5a7ed24078c23c12875007a767f1f5ecec3e6683 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Fri, 25 Aug 2017 17:01:29 +0100 Subject: [PATCH 303/720] allow tuples --- src/series.jl | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/series.jl b/src/series.jl index f4f277a8..f3499e22 100644 --- a/src/series.jl +++ b/src/series.jl @@ -509,6 +509,13 @@ end # nothing # end +splittable_kw(key, val, lengthGroup) = false +splittable_kw(key, val::AbstractArray, lengthGroup) = (key != :group) && size(val,1) == lengthGroup +splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup)) + +split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...] +split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val) + # split the group into 1 series per group, and set the label and idxfilter for each @recipe function f(groupby::GroupBy, args...) lengthGroup = maximum(union(groupby.groupIds...)) @@ -517,9 +524,8 @@ end label --> string(glab) idxfilter --> groupby.groupIds[i] for (key,val) in d - if key != :group && isa(val, AbstractArray) && size(val,1) >= lengthGroup - n = ndims(val) - :($key) := val[groupby.groupIds[i], fill(Colon(), n-1)...] + if splittable_kw(key, val, lengthGroup) + :($key) := split_kw(key, val, groupby.groupIds[i]) end end args From 78b0918216033b195494b7cc55709a2f6e7c212f Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 25 Aug 2017 13:54:56 -0400 Subject: [PATCH 304/720] gr: defer the calculation of padding constraints --- src/backends/gr.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 43e55d4f..d4d8e3bf 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -579,7 +579,7 @@ function gr_get_ticks_size(ticks, i) return l end -function _update_min_padding!(sp::Subplot{GRBackend}) +function gr_update_min_padding(sp::Subplot{GRBackend}) # Add margin given by the user leftpad = 2mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] @@ -622,6 +622,8 @@ end function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) + gr_update_min_padding(sp) + # the viewports for this subplot viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas) viewport_plotarea[:] = gr_viewport_from_bbox(sp, plotarea(sp), w, h, viewport_canvas) From a5751895f0e3807bb7ce5fff833134bd836671c7 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Sat, 26 Aug 2017 06:49:00 -0400 Subject: [PATCH 305/720] gr: update padding constraints before first plot --- src/backends/gr.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d4d8e3bf..8c32e6ec 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -579,7 +579,7 @@ function gr_get_ticks_size(ticks, i) return l end -function gr_update_min_padding(sp::Subplot{GRBackend}) +function _update_min_padding!(sp::Subplot{GRBackend}) # Add margin given by the user leftpad = 2mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] @@ -620,9 +620,8 @@ function gr_update_min_padding(sp::Subplot{GRBackend}) sp.minpad = (leftpad, toppad, rightpad, bottompad) end - function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) - gr_update_min_padding(sp) + _update_min_padding!(sp) # the viewports for this subplot viewport_subplot = gr_viewport_from_bbox(sp, bbox(sp), w, h, viewport_canvas) From 6cb1ed6c920cc7f95483affe4bd8b952e1fd7e4b Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sun, 27 Aug 2017 11:08:26 +0200 Subject: [PATCH 306/720] Remove hidden files when checking version numbers --- test/imgcomp.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index f3c0ee22..0a59e0df 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -42,7 +42,8 @@ function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = is fn = "ref$idx.png" # firgure out version info - versions = sort(VersionNumber.(readdir(refdir)), rev = true) + vns = filter(x->x[1] != '.', readdir(refdir)) + versions = sort(VersionNumber.(vns), rev = true) versions = filter(v -> v <= _current_plots_version, versions) # @show refdir fn versions From 5157089d876aab1f639a7e72d3e952687aaa21da Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Sun, 27 Aug 2017 18:56:10 +0100 Subject: [PATCH 307/720] group on a tuple of vectors --- src/args.jl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index ef403a04..3bd869f5 100644 --- a/src/args.jl +++ b/src/args.jl @@ -840,16 +840,24 @@ end # this is when given a vector-type of values to group by -function extractGroupArgs(v::AVec, args...) +function extractGroupArgs(v::AVec, args...; legendEntry = string) groupLabels = sort(collect(unique(v))) n = length(groupLabels) if n > 100 warn("You created n=$n groups... Is that intended?") end groupIds = Vector{Int}[filter(i -> v[i] == glab, 1:length(v)) for glab in groupLabels] - GroupBy(map(string, groupLabels), groupIds) + GroupBy(map(legendEntry, groupLabels), groupIds) end +legendEntryFromTuple(ns::Tuple) = string(("$n " for n in ns)...) + +# this is when given a tuple of vectors of values to group by +function extractGroupArgs(vs::Tuple, args...) + (vs == ()) && return GroupBy([""], [1:size(args[1],1)]) + v = collect(zip(vs...)) + extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple) +end # expecting a mapping of "group label" to "group indices" function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...) From d594ac2f00f7edf2b6d1d246ebb9b06f2dba60de Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 28 Aug 2017 18:16:10 +0100 Subject: [PATCH 308/720] Accept axis with 4 ticks --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 6ce1532c..850b67cb 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -185,7 +185,7 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) scaled_ticks = optimize_ticks( sf(amin), sf(amax); - k_min = 5, # minimum number of ticks + k_min = 4, # minimum number of ticks k_max = 8, # maximum number of ticks )[1] elseif typeof(ticks) <: Int From 25bcc3cbc159bc32e354442ef493af2e33a40cb8 Mon Sep 17 00:00:00 2001 From: Jonathan Goldfarb Date: Tue, 29 Aug 2017 12:19:01 -0400 Subject: [PATCH 309/720] Fix incorrect escape sequence error on v0.7. --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 203db58f..fb820b65 100644 --- a/src/args.jl +++ b/src/args.jl @@ -175,7 +175,7 @@ function hasgrid(arg::Symbol, letter) if arg in _allGridSyms arg in (:all, :both, :on) || contains(string(arg), string(letter)) else - warn("Unknown grid argument $arg; $letter\grid was set to `true` instead.") + warn("Unknown grid argument $arg; $letter\\grid was set to `true` instead.") true end end From e3cba22ab7e832c3f8730329133ed881f3157a23 Mon Sep 17 00:00:00 2001 From: Jonathan Goldfarb Date: Tue, 29 Aug 2017 13:29:30 -0400 Subject: [PATCH 310/720] Correct fix to warning for unknown grid argument. --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index fb820b65..0d6eeb6f 100644 --- a/src/args.jl +++ b/src/args.jl @@ -175,7 +175,7 @@ function hasgrid(arg::Symbol, letter) if arg in _allGridSyms arg in (:all, :both, :on) || contains(string(arg), string(letter)) else - warn("Unknown grid argument $arg; $letter\\grid was set to `true` instead.") + warn("Unknown grid argument $arg; $(Symbol(letter, :grid)) was set to `true` instead.") true end end From 41877e362aaa02d253c929cc43e04cf3f8434f71 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 29 Aug 2017 20:36:59 +0200 Subject: [PATCH 311/720] add origin framestyle --- src/args.jl | 3 ++- src/axes.jl | 6 ++++-- src/backends/pyplot.jl | 6 +++++- src/pipeline.jl | 5 +++++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/src/args.jl b/src/args.jl index 6afdd66b..500d0e68 100644 --- a/src/args.jl +++ b/src/args.jl @@ -181,13 +181,14 @@ function hasgrid(arg::Symbol, letter) end hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) -const _allFramestyles = [:box, :semi, :axes, :grid, :none] +const _allFramestyles = [:box, :semi, :axes, :origin, :grid, :none] const _framestyleAliases = Dict{Symbol, Symbol}( :frame => :box, :border => :box, :on => :box, :transparent => :semi, :semitransparent => :semi, + :zeroline => :origin, ) # ----------------------------------------------------------------------------- diff --git a/src/axes.jl b/src/axes.jl index 850b67cb..58134c29 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -515,7 +515,8 @@ function axis_drawing_info(sp::Subplot) if !(sp[:framestyle] == :none) # xaxis - sp[:framestyle] == :grid || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + sp[:framestyle] in (:grid, :origin) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + sp[:framestyle] == :origin && push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine if !(xaxis[:ticks] in (nothing, false)) f = scalefunc(yaxis[:scale]) @@ -531,7 +532,8 @@ function axis_drawing_info(sp::Subplot) end # yaxis - sp[:framestyle] == :grid || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + sp[:framestyle] in (:grid, :origin) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + sp[:framestyle] == :origin && push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine if !(yaxis[:ticks] in (nothing, false)) f = scalefunc(xaxis[:scale]) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 80a7f77c..72cc0ebd 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1099,9 +1099,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ax[:spines]["top"][:set_alpha](intensity) ax[:spines]["right"][:set_linewidth](intensity) ax[:spines]["top"][:set_linewidth](intensity) - elseif sp[:framestyle] == :axes + elseif sp[:framestyle] in (:axes, :origin) ax[:spines]["right"][:set_visible](false) ax[:spines]["top"][:set_visible](false) + if sp[:framestyle] == :origin + ax[:spines]["left"][:set_position]("zero") + ax[:spines]["bottom"][:set_position]("zero") + end elseif sp[:framestyle] in (:grid, :none) for (loc, spine) in ax[:spines] spine[:set_visible](false) diff --git a/src/pipeline.jl b/src/pipeline.jl index e0041b77..47c25abb 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -364,6 +364,11 @@ function _expand_subplot_extrema(sp::Subplot, d::KW, st::Symbol) elseif !(st in (:pie, :histogram, :bins2d, :histogram2d)) expand_extrema!(sp, d) end + # expand for zerolines (axes through origin) + if sp[:framestyle] == :origin + expand_extrema!(sp[:xaxis], 0.0) + expand_extrema!(sp[:yaxis], 0.0) + end end function _add_the_series(plt, sp, d) From f41426c85ad185a60cd05ba365ef6f8c27d01f8e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 29 Aug 2017 22:04:33 +0200 Subject: [PATCH 312/720] fix pyplot --- src/backends/pyplot.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 72cc0ebd..62a0b394 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1099,17 +1099,17 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ax[:spines]["top"][:set_alpha](intensity) ax[:spines]["right"][:set_linewidth](intensity) ax[:spines]["top"][:set_linewidth](intensity) - elseif sp[:framestyle] in (:axes, :origin) + elseif sp[:framestyle] == :axes ax[:spines]["right"][:set_visible](false) ax[:spines]["top"][:set_visible](false) - if sp[:framestyle] == :origin - ax[:spines]["left"][:set_position]("zero") - ax[:spines]["bottom"][:set_position]("zero") - end - elseif sp[:framestyle] in (:grid, :none) + elseif sp[:framestyle] in (:grid, :none, :origin) for (loc, spine) in ax[:spines] spine[:set_visible](false) end + if sp[:framestyle] == :origin + ax[:axhline](y = 0, color= py_color(sp[:xaxis][:foreground_color_axis]), lw = 0.5) + ax[:axvline](x = 0, color= py_color(sp[:yaxis][:foreground_color_axis]), lw = 0.5) + end end end end From a894d377dce49058887fff4b0e05e944233a27be Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 29 Aug 2017 23:34:07 +0200 Subject: [PATCH 313/720] add vectors to hold histogram-like seriestypes and friends --- src/args.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/args.jl b/src/args.jl index 6afdd66b..b305d613 100644 --- a/src/args.jl +++ b/src/args.jl @@ -80,9 +80,13 @@ const _typeAliases = Dict{Symbol,Symbol}( add_non_underscore_aliases!(_typeAliases) -like_histogram(seriestype::Symbol) = seriestype in (:histogram, :barhist, :barbins) -like_line(seriestype::Symbol) = seriestype in (:line, :path, :steppre, :steppost) -like_surface(seriestype::Symbol) = seriestype in (:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image) +const _histogram_like = [:histogram, :barhist, :barbins] +const _line_like = [:line, :path, :steppre, :steppost] +const _surface_like = [:contour, :contourf, :contour3d, :heatmap, :surface, :wireframe, :image] + +like_histogram(seriestype::Symbol) = seriestype in _histogram_like +like_line(seriestype::Symbol) = seriestype in _line_like +like_surface(seriestype::Symbol) = seriestype in _surface_like is3d(seriestype::Symbol) = seriestype in _3dTypes is3d(series::Series) = is3d(series.d) From 8beee23e2189c85c9fde568d9bfc01f087b95ac8 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 30 Aug 2017 09:59:23 +0200 Subject: [PATCH 314/720] gr: suppress default output in CI or Jupyter mode _update_min_padding() is called before the backend is "started". In GR, this triggers an automatic initialization and starts the default output driver (X11, Quartz or GDI). This doesn't make sense in headless testing environments (CI) or when using Plots in Jupyter notebooks. These patches correct this behavour - but it's unclear (to me), why the call of _update_min_padding() can't be postponed. --- src/backends/gr.jl | 3 +++ test/runtests.jl | 1 + 2 files changed, 4 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 177cd1b9..4f871e6a 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -580,6 +580,9 @@ function gr_get_ticks_size(ticks, i) end function _update_min_padding!(sp::Subplot{GRBackend}) + if !haskey(ENV, "GKSwstype") && isijulia() + ENV["GKSwstype"] = "svg" + end # Add margin given by the user leftpad = 2mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] diff --git a/test/runtests.jl b/test/runtests.jl index 69b4d393..da7fcb05 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,6 +8,7 @@ default(show=false, reuse=true) img_eps = isinteractive() ? 1e-2 : 10e-2 @testset "GR" begin + ENV["GKSwstype"] = "100" @test gr() == Plots.GRBackend() @test backend() == Plots.GRBackend() From c355e02a20db52e845b0d4c22753acc01af6fe90 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 29 Aug 2017 13:37:06 +0200 Subject: [PATCH 315/720] add nightly and 32-bit to allow-failures --- appveyor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index cc07d84a..81d2e51f 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -5,6 +5,12 @@ environment: - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" +matrix: + allow_failures: + - JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x86/0.6/julia-0.6-latest-win32.exe" #check and address + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x86/julia-latest-win32.exe" + - JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe" + notifications: - provider: Email on_build_success: false From 5e968e0aa84aa369ad4b5a8a19f761a40431740b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 Aug 2017 22:19:13 +0200 Subject: [PATCH 316/720] ticks to axes --- src/axes.jl | 16 ++++++++++++-- src/backends/glvisualize.jl | 12 +++++++---- src/backends/gr.jl | 4 ++-- src/backends/pyplot.jl | 43 +++++++++++++++++++------------------ 4 files changed, 46 insertions(+), 29 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 58134c29..6d321594 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -523,9 +523,15 @@ function axis_drawing_info(sp::Subplot) invf = invscalefunc(yaxis[:scale]) t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) + t3 = invf(f(0) - 0.015*(f(ymax)-f(ymin))) for xtick in xticks[1] - push!(xaxis_segs, (xtick, ymin), (xtick, t1)) # bottom tick + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, xaxis[:mirror] ? -t3 : t3) + else + xaxis[:mirror] ? (ymax, t2) : (ymin, t1) + end + push!(xaxis_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end @@ -540,9 +546,15 @@ function axis_drawing_info(sp::Subplot) invf = invscalefunc(xaxis[:scale]) t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) + t3 = invf(f(0) - 0.015*(f(xmax)-f(xmin))) for ytick in yticks[1] - push!(yaxis_segs, (xmin, ytick), (t1, ytick)) # left tick + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, yaxis[:mirror] ? -t3 : t3) + else + yaxis[:mirror] ? (xmax, t2) : (xmin, t1) + end + push!(yaxis_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 974b73b1..34dfdb36 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -604,7 +604,7 @@ end pointsize(font) = font.pointsize * 2 function draw_ticks( - axis, ticks, isx, lims, m, text = "", + axis, ticks, isx, isorigin, lims, m, text = "", positions = Point2f0[], offsets=Vec2f0[] ) sz = pointsize(axis[:tickfont]) @@ -622,7 +622,11 @@ function draw_ticks( for (cv, dv) in zip(ticks...) x, y = cv, lims[1] - xy = isx ? (x, y) : (y, x) + xy = if isorigin + isx ? (x, 0) : (0, x) + else + isx ? (x, y) : (y, x) + end _pos = m * GeometryTypes.Vec4f0(xy[1], xy[2], 0, 1) startpos = Point2f0(_pos[1], _pos[2]) - axis_gap str = string(dv) @@ -711,10 +715,10 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are if !(xaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none) ticklabels = map(model) do m mirror = xaxis[:mirror] - t, positions, offsets = draw_ticks(xaxis, xticks, true, ylim, m) + t, positions, offsets = draw_ticks(xaxis, xticks, true, sp[:framestyle] == :origin, ylim, m) mirror = xaxis[:mirror] t, positions, offsets = draw_ticks( - yaxis, yticks, false, xlim, m, + yaxis, yticks, false, sp[:framestyle] == :origin, xlim, m, t, positions, offsets ) end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 177cd1b9..517b48cb 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -793,7 +793,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) flip, mirror = gr_set_xticks_font(sp) for (cv, dv) in zip(xticks...) # use xor ($) to get the right y coords - xi, yi = GR.wctondc(cv, xor(flip, mirror) ? ymax : ymin) + xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3, string(dv)) end @@ -804,7 +804,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) flip, mirror = gr_set_yticks_font(sp) for (cv, dv) in zip(yticks...) # use xor ($) to get the right y coords - xi, yi = GR.wctondc(xor(flip, mirror) ? xmax : xmin, cv) + xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) end diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 62a0b394..5c40f284 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1040,6 +1040,28 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # ax[:set_title](sp[:title], loc = loc) end + # framestyle + if !ispolar(sp) && !is3d(sp) + if sp[:framestyle] == :semi + intensity = 0.5 + ax[:spines]["right"][:set_alpha](intensity) + ax[:spines]["top"][:set_alpha](intensity) + ax[:spines]["right"][:set_linewidth](intensity) + ax[:spines]["top"][:set_linewidth](intensity) + elseif sp[:framestyle] in (:axes, :origin) + ax[:spines]["right"][:set_visible](false) + ax[:spines]["top"][:set_visible](false) + if sp[:framestyle] == :origin + ax[:spines]["bottom"][:set_position]("zero") + ax[:spines]["left"][:set_position]("zero") + end + elseif sp[:framestyle] in (:grid, :none, :origin) + for (loc, spine) in ax[:spines] + spine[:set_visible](false) + end + end + end + # axis attributes for letter in (:x, :y, :z) axissym = Symbol(letter, :axis) @@ -1091,27 +1113,6 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # this sets the bg color inside the grid ax[set_facecolor_sym](py_color(sp[:background_color_inside])) - # framestyle - if !ispolar(sp) && !is3d(sp) - if sp[:framestyle] == :semi - intensity = 0.5 - ax[:spines]["right"][:set_alpha](intensity) - ax[:spines]["top"][:set_alpha](intensity) - ax[:spines]["right"][:set_linewidth](intensity) - ax[:spines]["top"][:set_linewidth](intensity) - elseif sp[:framestyle] == :axes - ax[:spines]["right"][:set_visible](false) - ax[:spines]["top"][:set_visible](false) - elseif sp[:framestyle] in (:grid, :none, :origin) - for (loc, spine) in ax[:spines] - spine[:set_visible](false) - end - if sp[:framestyle] == :origin - ax[:axhline](y = 0, color= py_color(sp[:xaxis][:foreground_color_axis]), lw = 0.5) - ax[:axvline](x = 0, color= py_color(sp[:yaxis][:foreground_color_axis]), lw = 0.5) - end - end - end end py_drawfig(fig) end From 3fd745a5df33e913bbce93f184f78bcdfc776af5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 Aug 2017 23:42:57 +0200 Subject: [PATCH 317/720] remove 0 tick label --- src/args.jl | 1 + src/axes.jl | 16 ++++++++++++++-- src/backends/pyplot.jl | 4 ++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index 500d0e68..5e9675c3 100644 --- a/src/args.jl +++ b/src/args.jl @@ -189,6 +189,7 @@ const _framestyleAliases = Dict{Symbol, Symbol}( :transparent => :semi, :semitransparent => :semi, :zeroline => :origin, + :zero => :origin, ) # ----------------------------------------------------------------------------- diff --git a/src/axes.jl b/src/axes.jl index 6d321594..db4e88fa 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -516,7 +516,13 @@ function axis_drawing_info(sp::Subplot) if !(sp[:framestyle] == :none) # xaxis sp[:framestyle] in (:grid, :origin) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis - sp[:framestyle] == :origin && push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) + if sp[:framestyle] == :origin + push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) + # don't show the 0 tick label for the origin framestyle + if length(yticks) > 1 + xticks[2][xticks[1] .== 0] = "" + end + end sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine if !(xaxis[:ticks] in (nothing, false)) f = scalefunc(yaxis[:scale]) @@ -539,7 +545,13 @@ function axis_drawing_info(sp::Subplot) # yaxis sp[:framestyle] in (:grid, :origin) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis - sp[:framestyle] == :origin && push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) + if sp[:framestyle] == :origin + push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) + # don't show the 0 tick label for the origin framestyle + if length(yticks) > 1 + yticks[2][yticks[1] .== 0] = "" + end + end sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine if !(yaxis[:ticks] in (nothing, false)) f = scalefunc(xaxis[:scale]) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 5c40f284..225987f7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1077,6 +1077,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) py_set_scale(ax, axis) py_set_lims(ax, axis) ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis) + # don't show the 0 tick label for the origin framestyle + if sp[:framestyle] == :origin && length(ticks) > 1 + ticks[2][ticks[1] .== 0] = "" + end py_set_ticks(ax, ticks, letter) ax[Symbol("set_", letter, "label")](axis[:guide]) if get(axis.d, :flip, false) From 6c548f025e1e0dea95fd9249f4644efbb804d143 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Thu, 31 Aug 2017 18:55:30 +0100 Subject: [PATCH 318/720] wip groupedbar --- src/series.jl | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/series.jl b/src/series.jl index f3499e22..246764d5 100644 --- a/src/series.jl +++ b/src/series.jl @@ -519,16 +519,31 @@ split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in va # split the group into 1 series per group, and set the label and idxfilter for each @recipe function f(groupby::GroupBy, args...) lengthGroup = maximum(union(groupby.groupIds...)) - for (i,glab) in enumerate(groupby.groupLabels) - @series begin - label --> string(glab) - idxfilter --> groupby.groupIds[i] - for (key,val) in d - if splittable_kw(key, val, lengthGroup) - :($key) := split_kw(key, val, groupby.groupIds[i]) + if !(RecipesBase.group_as_matrix(args[1])) + for (i,glab) in enumerate(groupby.groupLabels) + @series begin + label --> string(glab) + idxfilter --> groupby.groupIds[i] + for (key,val) in d + if splittable_kw(key, val, lengthGroup) + :($key) := split_kw(key, val, groupby.groupIds[i]) + end end + args end - args end + else + g = args[1] + x, y = g.args + x_u = unique(x) + y_mat = Array{eltype(y)}(length(x_u), length(groupby.groupLabels)) + for i in 1:length(groupby.groupLabels) + xi = x[groupby.groupIds[i]] + yi = y[groupby.groupIds[i]] + x2y = Dict(zip(xi,yi)) + y_mat[:, i] = [get(x2y, s, NaN) for s in x_u] + end + label --> reshape(groupby.groupLabels, 1, :) + typeof(g)((x_u, y_mat)) end end From 17c10bbe68b5148b3a1a645401bec275f43af212 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 28 Aug 2017 11:06:51 +0200 Subject: [PATCH 319/720] Reduce margin to 10 px --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index d1775f47..4393ab60 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -290,7 +290,7 @@ PlotExample("Layouts, margins, label rotation, title location", [:(begin plot(rand(100,6),layout=@layout([a b; c]),title=["A" "B" "C"], title_location=:left, left_margin=[20mm 0mm], - bottom_margin=50px, xrotation=60) + bottom_margin=10px, xrotation=60) end)] ), From e92fbadc3ada19f4162454451961cfe9eebdbde3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 23 Aug 2017 19:53:33 +0200 Subject: [PATCH 320/720] Update histogram normalization desc --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 2aad42a5..51ae0d80 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -40,7 +40,7 @@ const _arg_desc = KW( :ribbon => "Number or AbstractVector. Creates a fillrange around the data points.", :quiver => "AbstractVector or 2-Tuple of vectors. The directional vectors U,V which specify velocity/gradient vectors for a quiver plot.", :arrow => "nothing (no arrows), Bool (if true, default arrows), Arrow object, or arg(s) that could be style or head length/widths. Defines arrowheads that should be displayed at the end of path line segments (just before a NaN and the last non-NaN point). Used in quiverplot, streamplot, or similar.", -:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a PDF with integral of 1) and :density (only normalize in respect to bin sizes).", +:normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).", :weights => "AbstractVector. Used in histogram types for weighted counts.", :contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.", :match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.", From 62694e4a9382e5efab387bf86e86f7a3c1e4ac63 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 31 Aug 2017 23:19:00 +0200 Subject: [PATCH 321/720] Make Freedman-Diaconis the default --- src/recipes.jl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 393bc2d4..0708667f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -510,8 +510,10 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode v = vs[dim] if mode == :auto - 30 - elseif mode == :sqrt # Square-root choice + mode == :fd + end + + if mode == :sqrt # Square-root choice _cl(sqrt(n)) elseif mode == :sturges # Sturges' formula _cl(log2(n)) + 1 @@ -550,7 +552,7 @@ end @recipe function f(::Type{Val{:histogram}}, x, y, z) - seriestype := :barhist + seriestype := length(y) > 1e6 ? :stephist : :barhist () end @deps histogram barhist From cd1913c00886e1c5ccc0c1e06ea7aee8bdb83efc Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 31 Aug 2017 23:20:55 +0200 Subject: [PATCH 322/720] Update bins description --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 51ae0d80..8634eabb 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -21,7 +21,7 @@ const _arg_desc = KW( :markerstrokewidth => "Number. Width of the marker stroke (border. in pixels)", :markerstrokecolor => "Color Type. Color of the marker stroke (border). `:match` will take the value from `:foreground_color_subplot`.", :markerstrokealpha => "Number in [0,1]. The alpha/opacity override for the marker stroke (border). `nothing` (the default) means it will take the alpha value of markerstrokecolor.", -:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto. For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `linspace(extrema(x)..., 25)`", +:bins => "Integer, NTuple{2,Integer}, AbstractVector or Symbol. Default is :auto (the Freedman-Diaconis rule). For histogram-types, defines the approximate number of bins to aim for, or the auto-binning algorithm to use (:sturges, :sqrt, :rice, :scott or :fd). For fine-grained control pass a Vector of break values, e.g. `linspace(extrema(x)..., 25)`", :smooth => "Bool. Add a regression line?", :group => "AbstractVector. Data is split into a separate series, one for each unique value in `group`.", :x => "Various. Input data. First Dimension", From 2dcf7fb3ddabaf4ba06a4f82da8ea0c841f9c7e1 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 31 Aug 2017 23:58:07 +0200 Subject: [PATCH 323/720] Change default bar width to 0.8 --- src/args.jl | 2 ++ src/axes.jl | 2 +- src/recipes.jl | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index b305d613..d47438f9 100644 --- a/src/args.jl +++ b/src/args.jl @@ -193,6 +193,8 @@ const _framestyleAliases = Dict{Symbol, Symbol}( :transparent => :semi, :semitransparent => :semi, ) + +const _bar_width = 0.8 # ----------------------------------------------------------------------------- const _series_defaults = KW( diff --git a/src/axes.jl b/src/axes.jl index 850b67cb..959274bc 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -365,7 +365,7 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = ignorenan_mean(diff(data)) + bw = d[:bar_width] = _bar_width * ignorenan_mean(diff(data)) end axis = sp.attr[Symbol(dsym, :axis)] expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw)) diff --git a/src/recipes.jl b/src/recipes.jl index 393bc2d4..418364b0 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -289,7 +289,7 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5ignorenan_mean(diff(procx)) + 0.5*_bar_width*ignorenan_mean(diff(procx)) else Float64[0.5_cycle(bw,i) for i=1:length(procx)] end From 4320c7b9fbc6a49d9fa50fb8430ab09568c6b615 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Fri, 1 Sep 2017 07:36:49 +0200 Subject: [PATCH 324/720] gr: suppress default output in Juno --- src/backends/gr.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 4f871e6a..76faa6fd 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -580,8 +580,10 @@ function gr_get_ticks_size(ticks, i) end function _update_min_padding!(sp::Subplot{GRBackend}) - if !haskey(ENV, "GKSwstype") && isijulia() - ENV["GKSwstype"] = "svg" + if !haskey(ENV, "GKSwstype") + if isijulia() || (isdefined(Main, :Juno) && Juno.isactive()) + ENV["GKSwstype"] = "svg" + end end # Add margin given by the user leftpad = 2mm + sp[:left_margin] From d77be82a99a55c468990e8a056fc28b4d6be31c0 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 1 Sep 2017 10:36:44 +0200 Subject: [PATCH 325/720] fix classic typo --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 0708667f..d4d1b201 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -510,7 +510,7 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode v = vs[dim] if mode == :auto - mode == :fd + mode = :fd end if mode == :sqrt # Square-root choice From 4be19ba6d85d0f4a85f12b24f6eff94ecb0bc573 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 29 Aug 2017 14:15:39 +0200 Subject: [PATCH 326/720] Make wand edges possible in statplots --- src/recipes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index d4d1b201..86b4da00 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -497,6 +497,7 @@ end end Plots.@deps stepbins path +wand_edges(x...) = error("Load the StatPlots package in order to use :wand bins") function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) _cl(x) = ceil(Int, NaNMath.max(x, one(x))) @@ -529,8 +530,11 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode end _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) -_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning +function _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) + binning == :wand && return(wand_edges(vs[dim])) + _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) +end _hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) = map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...)) From e47dde9f41f6d6056dc72b80ea0aea6f79fd02dd Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 1 Sep 2017 16:14:29 +0200 Subject: [PATCH 327/720] simplify but creates type instability --- src/recipes.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 86b4da00..6de497e1 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -497,7 +497,7 @@ end end Plots.@deps stepbins path -wand_edges(x...) = error("Load the StatPlots package in order to use :wand bins") +wand_edges(x...) = (warn("Load the StatPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto) function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) _cl(x) = ceil(Int, NaNMath.max(x, one(x))) @@ -524,17 +524,16 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode _cl(_span(v) / (3.5 * std(v) / n^(1/3))) elseif mode == :fd # Freedman–Diaconis rule _cl(_span(v) / (2 * _iqr(v) / n^(1/3))) + elseif mode == :wand + wand_edges(v) # this makes this function not type stable, but the type instability does not propagate else error("Unknown auto-binning mode $mode") - end::Int + end end _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning -function _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) - binning == :wand && return(wand_edges(vs[dim])) - _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) -end +_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) _hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) = map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...)) From a1896d189c0d85432b9ee3391a5ece829d6f9ff0 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 1 Sep 2017 16:31:13 +0200 Subject: [PATCH 328/720] Revert ordering --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 6de497e1..4724313e 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -532,8 +532,8 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode end _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) -_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning _hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) +_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning _hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) = map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...)) From 456b8258c37d3be3418bd06f2be6a1c9bdfbfb95 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 2 Sep 2017 02:35:26 +0200 Subject: [PATCH 329/720] add zerolines framestyle --- src/args.jl | 4 +--- src/axes.jl | 26 +++++++++++++++----------- src/backends/glvisualize.jl | 21 ++++++++++++++++++++- src/backends/gr.jl | 21 ++++++++++++++++++++- src/backends/pyplot.jl | 13 +++++++++---- src/pipeline.jl | 2 +- 6 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/args.jl b/src/args.jl index 5e9675c3..30133390 100644 --- a/src/args.jl +++ b/src/args.jl @@ -181,15 +181,13 @@ function hasgrid(arg::Symbol, letter) end hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) -const _allFramestyles = [:box, :semi, :axes, :origin, :grid, :none] +const _allFramestyles = [:box, :semi, :axes, :origin, :zerolines, :grid, :none] const _framestyleAliases = Dict{Symbol, Symbol}( :frame => :box, :border => :box, :on => :box, :transparent => :semi, :semitransparent => :semi, - :zeroline => :origin, - :zero => :origin, ) # ----------------------------------------------------------------------------- diff --git a/src/axes.jl b/src/axes.jl index db4e88fa..5c7c7649 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -508,6 +508,8 @@ function axis_drawing_info(sp::Subplot) yticks = get_ticks(yaxis) xaxis_segs = Segments(2) yaxis_segs = Segments(2) + xtick_segs = Segments(2) + ytick_segs = Segments(2) xgrid_segs = Segments(2) ygrid_segs = Segments(2) xborder_segs = Segments(2) @@ -515,12 +517,13 @@ function axis_drawing_info(sp::Subplot) if !(sp[:framestyle] == :none) # xaxis - sp[:framestyle] in (:grid, :origin) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis - if sp[:framestyle] == :origin + sp[:framestyle] in (:grid, :origin, :zerolines) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + if sp[:framestyle] in (:origin, :zerolines) push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) # don't show the 0 tick label for the origin framestyle - if length(yticks) > 1 - xticks[2][xticks[1] .== 0] = "" + if sp[:framestyle] == :origin && length(xticks) > 1 + showticks = xticks[1] .!= 0 + xticks = (xticks[1][showticks], xticks[2][showticks]) end end sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine @@ -537,19 +540,20 @@ function axis_drawing_info(sp::Subplot) else xaxis[:mirror] ? (ymax, t2) : (ymin, t1) end - push!(xaxis_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick + push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end end # yaxis - sp[:framestyle] in (:grid, :origin) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis - if sp[:framestyle] == :origin + sp[:framestyle] in (:grid, :origin, :zerolines) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + if sp[:framestyle] in (:origin, :zerolines) push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) # don't show the 0 tick label for the origin framestyle - if length(yticks) > 1 - yticks[2][yticks[1] .== 0] = "" + if sp[:framestyle] == :origin && length(yticks) > 1 + showticks = yticks[1] .!= 0 + yticks = (yticks[1][showticks], yticks[2][showticks]) end end sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine @@ -566,12 +570,12 @@ function axis_drawing_info(sp::Subplot) else yaxis[:mirror] ? (xmax, t2) : (xmin, t1) end - push!(yaxis_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick + push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end end end - xticks, yticks, xaxis_segs, yaxis_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs + xticks, yticks, xaxis_segs, yaxis_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 34dfdb36..f9c01f29 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -682,7 +682,7 @@ function text_model(font, pivot) end end function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, area) - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = Plots.axis_drawing_info(sp) xaxis = sp[:xaxis]; yaxis = sp[:yaxis] xgc = Colors.color(Plots.gl_color(xaxis[:foreground_color_grid])) @@ -707,6 +707,25 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are spine = draw_grid_lines(sp, yspine_segs, 1f0, :solid, model, RGBA(yac, 1.0f0)) push!(axis_vis, spine) end + if sp[:framestyle] in (:zerolines, :grid) + if alpha(xaxis[:foreground_color_grid]) > 0 + spine = draw_grid_lines(sp, xtick_segs, 1f0, :solid, model, RGBA(xgc, xaxis[:gridalpha])) + push!(axis_vis, spine) + end + if alpha(yaxis[:foreground_color_grid]) > 0 + spine = draw_grid_lines(sp, ytick_segs, 1f0, :solid, model, RGBA(ygc, yaxis[:gridalpha])) + push!(axis_vis, spine) + end + else + if alpha(xaxis[:foreground_color_axis]) > 0 + spine = draw_grid_lines(sp, xtick_segs, 1f0, :solid, model, RGBA(xac, 1.0f0)) + push!(axis_vis, spine) + end + if alpha(yaxis[:foreground_color_axis]) > 0 + spine = draw_grid_lines(sp, ytick_segs, 1f0, :solid, model, RGBA(yac, 1.0f0)) + push!(axis_vis, spine) + end + end fcolor = Plots.gl_color(xaxis[:foreground_color_axis]) xlim = Plots.axis_limits(xaxis) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 517b48cb..654b4e41 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -760,7 +760,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setwindow(xmin, xmax, ymin, ymax) end - xticks, yticks, xspine_segs, yspine_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp) + xticks, yticks, xspine_segs, yspine_segs, xtick_segs, ytick_segs, xgrid_segs, ygrid_segs, xborder_segs, yborder_segs = axis_drawing_info(sp) # @show xticks yticks #spine_segs grid_segs # draw the grid lines @@ -787,6 +787,25 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_polyline(coords(yspine_segs)...) GR.setclip(1) + # axis ticks + if sp[:framestyle] in (:zerolines, :grid) + gr_set_line(1, :solid, xaxis[:foreground_color_grid]) + GR.settransparency(xaxis[:gridalpha]) + else + gr_set_line(1, :solid, xaxis[:foreground_color_axis]) + end + GR.setclip(0) + gr_polyline(coords(xtick_segs)...) + if sp[:framestyle] in (:zerolines, :grid) + gr_set_line(1, :solid, yaxis[:foreground_color_grid]) + GR.settransparency(yaxis[:gridalpha]) + else + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + end + GR.setclip(0) + gr_polyline(coords(ytick_segs)...) + GR.setclip(1) + # tick marks if !(xticks in (:none, nothing, false)) # x labels diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 225987f7..451f67ad 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -971,14 +971,15 @@ function py_set_scale(ax, axis::Axis) end -function py_set_axis_colors(ax, a::Axis) +function py_set_axis_colors(sp, ax, a::Axis) for (loc, spine) in ax[:spines] spine[:set_color](py_color(a[:foreground_color_border])) end axissym = Symbol(a[:letter], :axis) if haskey(ax, axissym) + tickcolor = sp[:framestyle] == :zerolines ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis]) ax[:tick_params](axis=string(a[:letter]), which="both", - colors=py_color(a[:foreground_color_axis]), + colors=tickcolor, labelcolor=py_color(a[:foreground_color_text])) ax[axissym][:label][:set_color](py_color(a[:foreground_color_guide])) end @@ -1055,10 +1056,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ax[:spines]["bottom"][:set_position]("zero") ax[:spines]["left"][:set_position]("zero") end - elseif sp[:framestyle] in (:grid, :none, :origin) + elseif sp[:framestyle] in (:grid, :none, :zerolines) for (loc, spine) in ax[:spines] spine[:set_visible](false) end + if sp[:framestyle] == :zerolines + ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = 0.75) + ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = 0.75) + end end end @@ -1102,7 +1107,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) alpha = axis[:gridalpha]) ax[:set_axisbelow](true) end - py_set_axis_colors(ax, axis) + py_set_axis_colors(sp, ax, axis) end # aspect ratio diff --git a/src/pipeline.jl b/src/pipeline.jl index 47c25abb..a0f17ba4 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -365,7 +365,7 @@ function _expand_subplot_extrema(sp::Subplot, d::KW, st::Symbol) expand_extrema!(sp, d) end # expand for zerolines (axes through origin) - if sp[:framestyle] == :origin + if sp[:framestyle] in (:origin, :zerolines) expand_extrema!(sp[:xaxis], 0.0) expand_extrema!(sp[:yaxis], 0.0) end From b3f59396895cdf8a1b43d0b3f922861671e710a3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 2 Sep 2017 22:58:26 +0200 Subject: [PATCH 330/720] make seriestype error more descriptive --- src/args.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/args.jl b/src/args.jl index b305d613..d582af9c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1276,6 +1276,7 @@ end # ----------------------------------------------------------------------------- +has_black_border_for_default(st) = error("The seriestype attribute only accepts Symbols, you passed $st.") function has_black_border_for_default(st::Symbol) like_histogram(st) || st in (:hexbin, :bar, :shape) end From ae6c1c0c663633cbd9cf4fe11a6d070b310c31f9 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 2 Sep 2017 23:19:29 +0200 Subject: [PATCH 331/720] make it even more descriptive --- src/args.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index d582af9c..8faded96 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1276,7 +1276,8 @@ end # ----------------------------------------------------------------------------- -has_black_border_for_default(st) = error("The seriestype attribute only accepts Symbols, you passed $st.") +has_black_border_for_default(st) = error("The seriestype attribute only accepts Symbols, you passed the $(typeof(st)) $st.") +has_black_border_for_default(st::Function) = error("The seriestype attribute only accepts Symbols, you passed the function $st.") function has_black_border_for_default(st::Symbol) like_histogram(st) || st in (:hexbin, :bar, :shape) end From 654fa0426b1947259830f449756260d35ae10793 Mon Sep 17 00:00:00 2001 From: JackDevine Date: Sun, 3 Sep 2017 12:53:49 +1200 Subject: [PATCH 332/720] Remove documentation --- src/arg_desc.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 50cf0a45..f244ff99 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -48,7 +48,6 @@ const _arg_desc = KW( :series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", :primary => "Bool. Does this count as a 'real series'? For example, you could have a path (primary), and a scatter (secondary) as 2 separate series, maybe with different data (see sticks recipe for an example). The secondary series will get the same color, etc as the primary.", :hover => "nothing or vector of strings. Text to display when hovering over each data point.", -:stride => "(1,1). Array row and column strides. Used in surface/wireframe.", # plot args :plot_title => "String. Title for the whole plot (not the subplots) (Note: Not currently implemented)", From e2795341d96729dc2ec3d59287ec63500002bcd6 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 4 Sep 2017 09:48:49 +0100 Subject: [PATCH 333/720] moved group_as_matrix to Plots --- src/series.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index 246764d5..99feb861 100644 --- a/src/series.jl +++ b/src/series.jl @@ -516,10 +516,12 @@ splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengt split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...] split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val) +group_as_matrix(t) = false + # split the group into 1 series per group, and set the label and idxfilter for each @recipe function f(groupby::GroupBy, args...) lengthGroup = maximum(union(groupby.groupIds...)) - if !(RecipesBase.group_as_matrix(args[1])) + if !(group_as_matrix(args[1])) for (i,glab) in enumerate(groupby.groupLabels) @series begin label --> string(glab) From 0f28b59c5f1467a6293b36efb8932d7c46708075 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 4 Sep 2017 09:57:33 +0100 Subject: [PATCH 334/720] added support for 1 or 3 arguments to group as matrix --- src/series.jl | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/series.jl b/src/series.jl index 99feb861..f4cb4b8f 100644 --- a/src/series.jl +++ b/src/series.jl @@ -516,6 +516,16 @@ splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengt split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...] split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val) +function build_arg_mat(x_ind, x, y, groupby) + y_mat = fill(NaN, length(keys(x_ind)), length(groupby.groupLabels)) + for i in 1:length(groupby.groupLabels) + xi = x[groupby.groupIds[i]] + yi = y[groupby.groupIds[i]] + y_mat[getindex.(x_ind, xi), i] = yi + end + return y_mat +end + group_as_matrix(t) = false # split the group into 1 series per group, and set the label and idxfilter for each @@ -536,16 +546,19 @@ group_as_matrix(t) = false end else g = args[1] - x, y = g.args - x_u = unique(x) - y_mat = Array{eltype(y)}(length(x_u), length(groupby.groupLabels)) - for i in 1:length(groupby.groupLabels) - xi = x[groupby.groupIds[i]] - yi = y[groupby.groupIds[i]] - x2y = Dict(zip(xi,yi)) - y_mat[:, i] = [get(x2y, s, NaN) for s in x_u] + if length(g.args) == 1 + x = zeros(Int64, lengthGroup) + for indexes in groupby.groupIds + x[indexes] = 1:length(indexes) + end + last_args = g.args + else + x = g.args[1] + last_args = g.args[2:end] end + x_u = unique(x) + x_ind = Dict(zip(x_u, 1:length(x_u))) label --> reshape(groupby.groupLabels, 1, :) - typeof(g)((x_u, y_mat)) + typeof(g)((x_u, (build_arg_mat(x_ind, x, arg, groupby) for arg in last_args)...)) end end From c8a7a050dec58fcf1aeab0c75ea7d23e744b5a87 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 4 Sep 2017 12:02:19 +0200 Subject: [PATCH 335/720] Update News.md with 12.4 improvements --- NEWS.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 8a7e19d7..603ed9da 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,11 +6,27 @@ - All new development should target 0.12! - Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - - `backports` branch is for Julia 0.4 + - `backports` branch is for Julia 0.5 --- ## (current master) +## 0.12.4 + +- added a new `framestyle` argument with choices: :box, :semi, :axes, :grid and :none +- changed the default bar width to 0.8 +- added working ribbon to plotly backend +- ensure that automatic ticks always generate 4 to 8 ticks +- group now groups keyword arguments of the same length as the input +- allow passing DateTime objects as ticks +- allow specifying the number of ticks as an integre +- fix bug on errorbars in gr +- fixed some but not all world age issues +- better margin with room for text +- added a `match` option for linecolor +- better error message un unsupported series types +- add a 'stride' keyword for the pyplot backend + ## 0.12.3 - new grid line style defaults From 4f8fc61689239d3ae0aec981e6a2dd08680567bb Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 4 Sep 2017 12:02:34 +0200 Subject: [PATCH 336/720] Turn off precompile for release --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index c75a8e65..1af493c7 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 4c2b01ccb02569ef3ae3a7951958061bb2709cbf Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 4 Sep 2017 12:18:10 +0200 Subject: [PATCH 337/720] change version number for testing --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 0a59e0df..d59aa5fa 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.12.3" +const _current_plots_version = v"0.12.4" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 9a2a54b8858528193b6e8a69a9ff1ff16adbf8cd Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 4 Sep 2017 13:09:37 +0200 Subject: [PATCH 338/720] reactivate precompilation on master --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 1af493c7..c75a8e65 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From dee24e6f08e1f0f76c18d8bb1e85f281bed28f86 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Mon, 4 Sep 2017 11:49:18 +0100 Subject: [PATCH 339/720] add kw support --- src/series.jl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/series.jl b/src/series.jl index f4cb4b8f..31191fd2 100644 --- a/src/series.jl +++ b/src/series.jl @@ -516,8 +516,9 @@ splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengt split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...] split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val) -function build_arg_mat(x_ind, x, y, groupby) - y_mat = fill(NaN, length(keys(x_ind)), length(groupby.groupLabels)) +function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1]) + y_mat = Array{promote_type(eltype(y), typeof(def_val))}(length(keys(x_ind)), length(groupby.groupLabels)) + fill!(y_mat, def_val) for i in 1:length(groupby.groupLabels) xi = x[groupby.groupIds[i]] yi = y[groupby.groupIds[i]] @@ -526,6 +527,8 @@ function build_arg_mat(x_ind, x, y, groupby) return y_mat end +groupedvec2mat(x_ind, x, y::Tuple, groupby) = Tuple(groupedvec2mat(x_ind, x, v, groupby) for v in y) + group_as_matrix(t) = false # split the group into 1 series per group, and set the label and idxfilter for each @@ -558,7 +561,12 @@ group_as_matrix(t) = false end x_u = unique(x) x_ind = Dict(zip(x_u, 1:length(x_u))) + for (key,val) in d + if splittable_kw(key, val, lengthGroup) + :($key) := groupedvec2mat(x_ind, x, val, groupby) + end + end label --> reshape(groupby.groupLabels, 1, :) - typeof(g)((x_u, (build_arg_mat(x_ind, x, arg, groupby) for arg in last_args)...)) + typeof(g)((x_u, (groupedvec2mat(x_ind, x, arg, groupby, NaN) for arg in last_args)...)) end end From d6e5b57a089ba236c7df4d1ba1d20669bf809ad3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 5 Sep 2017 14:01:59 +0200 Subject: [PATCH 340/720] fix-2dhistogram-bins --- src/recipes.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 208a4360..aeee2bc9 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -506,7 +506,8 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode n_samples = length(linearindices(first(vs))) # Estimator for number of samples in one row/column of bins along each axis: - n = max(1, n_samples^(1/N)) + nd = n_samples^(1/(2+N)) + v = vs[dim] @@ -515,15 +516,15 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode end if mode == :sqrt # Square-root choice - _cl(sqrt(n)) + _cl(sqrt(n_samples)) elseif mode == :sturges # Sturges' formula - _cl(log2(n)) + 1 + _cl(log2(n_samples)) + 1 elseif mode == :rice # Rice Rule - _cl(2 * n^(1/3)) + _cl(2 * nd) elseif mode == :scott # Scott's normal reference rule - _cl(_span(v) / (3.5 * std(v) / n^(1/3))) + _cl(_span(v) / (3.5 * std(v) / nd)) elseif mode == :fd # Freedman–Diaconis rule - _cl(_span(v) / (2 * _iqr(v) / n^(1/3))) + _cl(_span(v) / (2 * _iqr(v) / nd)) elseif mode == :wand wand_edges(v) # this makes this function not type stable, but the type instability does not propagate else From cd9f00300cacbf91cd5ca3526666be3da22a1211 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 5 Sep 2017 15:40:11 +0200 Subject: [PATCH 341/720] Add correction for correlations --- src/recipes.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index aeee2bc9..4105f7c5 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -505,9 +505,10 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode _span(v) = ignorenan_maximum(v) - ignorenan_minimum(v) n_samples = length(linearindices(first(vs))) - # Estimator for number of samples in one row/column of bins along each axis: - nd = n_samples^(1/(2+N)) + # The nd estimator is the key to most automatic binning methods, and is modified for twodimensional histograms to include correlation + nd = n_samples^(1/(2+N)) + nd = N == 2 ? nd / (1-cor(first(vs), last(vs))^2)^(3//8) : nd # the >2-dimensional case does not have a nice solution to correlations v = vs[dim] From 20ef846c38d33b44cbbf36d6ba0ab86362d9ad76 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 5 Sep 2017 22:42:05 +0200 Subject: [PATCH 342/720] move bracket in Sturges --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 4105f7c5..61d3de87 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -519,7 +519,7 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode if mode == :sqrt # Square-root choice _cl(sqrt(n_samples)) elseif mode == :sturges # Sturges' formula - _cl(log2(n_samples)) + 1 + _cl(log2(n_samples) + 1) elseif mode == :rice # Rice Rule _cl(2 * nd) elseif mode == :scott # Scott's normal reference rule From 331dd49326f2306899b5e0aed8f0bacb04cedd5f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 6 Sep 2017 16:03:39 +0200 Subject: [PATCH 343/720] improve recipe error --- src/series.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/series.jl b/src/series.jl index f3499e22..c6eee4b3 100644 --- a/src/series.jl +++ b/src/series.jl @@ -10,6 +10,9 @@ const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) +# unknown +convertToAnyVector(x, d::KW) = error("No user recipe defined for $(typeof(x))") + # missing convertToAnyVector(v::Void, d::KW) = Any[nothing], nothing From c89b125b9a09bc0f7a42fcb3a572f1ba7bd6c844 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 6 Sep 2017 19:09:52 +0200 Subject: [PATCH 344/720] implement framestyles for plotly(js) --- src/backends/plotly.jl | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1bd9f096..8da2be0f 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -33,6 +33,7 @@ const _plotly_attr = merge_with_base_supported([ :inset_subplots, :bar_width, :clims, + :framestyle, ]) const _plotly_seriestype = [ @@ -47,6 +48,17 @@ const _plotly_marker = [ const _plotly_scale = [:identity, :log10] is_subplot_supported(::PlotlyBackend) = true # is_string_supported(::PlotlyBackend) = true +const _plotly_framestyles = [:box, :axes, :zerolines, :grid, :none] +const _plotly_framestyle_defaults = Dict(:semi => :box, :origin => :zerolines) +function _plotly_framestyle(style::Symbol) + if style in _plotly_framestyles + return style + else + default_style = get(_plotly_framestyle_defaults, style, :axes) + warn("Framestyle :$style is not supported by Plotly and PlotlyJS. :$default_style was cosen instead.") + default_style + end +end # -------------------------------------------------------------------------------------- @@ -212,13 +224,19 @@ end function plotly_axis(axis::Axis, sp::Subplot) letter = axis[:letter] + framestyle = sp[:framestyle] ax = KW( + :visible => framestyle != :none, :title => axis[:guide], :showgrid => axis[:grid], :gridcolor => rgba_string(plot_color(axis[:foreground_color_grid], axis[:gridalpha])), :gridwidth => axis[:gridlinewidth], - :zeroline => false, + :zeroline => framestyle == :zerolines, + :zerolinecolor => rgba_string(axis[:foreground_color_axis]), + :showline => framestyle in (:box, :axes), + :linecolor => rgba_string(plot_color(axis[:foreground_color_axis])), :ticks => "inside", + :mirror => framestyle == :box, ) if letter in (:x,:y) @@ -232,7 +250,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) - ax[:tickcolor] = rgba_string(axis[:foreground_color_axis]) + ax[:tickcolor] = framestyle in (:zerolines, :grid) ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) # lims @@ -299,6 +317,9 @@ function plotly_layout(plt::Plot) d_out[:plot_bgcolor] = rgba_string(sp[:background_color_inside]) + # set to supported framestyle + sp[:framestyle] = _plotly_framestyle(sp[:framestyle]) + # if any(is3d, seriesargs) if is3d(sp) d_out[:scene] = KW( From fe0ea168f3310f89635b3eb191a30c9a65afb2bd Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Fri, 8 Sep 2017 03:18:46 -0500 Subject: [PATCH 345/720] histogram: ensure the number of bins is finite --- src/recipes.jl | 2 +- test/runtests.jl | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 61d3de87..876b3897 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -501,7 +501,7 @@ wand_edges(x...) = (warn("Load the StatPlots package in order to use :wand bins. function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) _cl(x) = ceil(Int, NaNMath.max(x, one(x))) - _iqr(v) = quantile(v, 0.75) - quantile(v, 0.25) + _iqr(v) = (q = quantile(v, 0.75) - quantile(v, 0.25); q > 0 ? q : oftype(q, 1)) _span(v) = ignorenan_maximum(v) - ignorenan_minimum(v) n_samples = length(linearindices(first(vs))) diff --git a/test/runtests.jl b/test/runtests.jl index da7fcb05..3f471735 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -129,6 +129,9 @@ end @test Plots.ignorenan_extrema(axis) == (0.5, 7.5) end +@testset "NoFail" begin + histogram([1, 0, 0, 0, 0, 0]) +end # tests for preprocessing recipes From 13111b377996961fee5e0ae2943aa7bccf6224b5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 8 Sep 2017 22:50:25 +0200 Subject: [PATCH 346/720] fix marker_z for GR --- src/backends/gr.jl | 52 ++++++++++++++++++++++++++-------------------- src/utils.jl | 22 ++++++++++++++++++++ test/runtests.jl | 2 +- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6baac621..c58e4356 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -264,17 +264,18 @@ function gr_fill_viewport(vp::AVec{Float64}, c) end -normalize_zvals(zv::Void) = zv -function normalize_zvals(zv::AVec) +normalize_zvals(args...) = nothing +function normalize_zvals(zv::AVec, clims::NTuple{2, <:Real}) vmin, vmax = ignorenan_extrema(zv) + isfinite(clims[1]) && (vmin = clims[1]) + isfinite(clims[2]) && (vmax = clims[2]) if vmin == vmax zeros(length(zv)) else - (zv - vmin) ./ (vmax - vmin) + clamp.((zv - vmin) ./ (vmax - vmin), 0, 1) end end - gr_alpha(α::Void) = 1 gr_alpha(α::Real) = α @@ -335,14 +336,14 @@ function gr_draw_markers(series::Series, x, y, msize, mz) end end -function gr_draw_markers(series::Series, x, y) +function gr_draw_markers(series::Series, x, y, clims) isempty(x) && return - mz = normalize_zvals(series[:marker_z]) + mz = normalize_zvals(series[:marker_z], clims) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_draw_markers(series, x, y, series[:markersize], mz) if mz != nothing GR.setscale(0) - gr_colorbar(series[:subplot]) + gr_colorbar(series[:subplot], clims) end end @@ -453,6 +454,20 @@ function gr_colorbar(sp::Subplot) end end +function gr_colorbar(sp::Subplot, clims) + if sp[:colorbar] != :none + xmin, xmax = gr_xy_axislims(sp)[1:2] + gr_set_viewport_cmap(sp) + l = zeros(Int32, 1, 256) + l[1,:] = Int[round(Int, _i) for _i in linspace(1000, 1255, 256)] + GR.setwindow(xmin, xmax, clims[1], clims[2]) + GR.cellarray(xmin, xmax, clims[2], clims[1], 1, length(l), l) + ztick = 0.5 * GR.tick(clims[1], clims[2]) + GR.axes(0, ztick, xmax, clims[1], 0, 1, 0.005) + gr_set_viewport_plotarea() + end +end + gr_view_xcenter() = 0.5 * (viewport_plotarea[1] + viewport_plotarea[2]) gr_view_ycenter() = 0.5 * (viewport_plotarea[3] + viewport_plotarea[4]) @@ -877,6 +892,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # this needs to be here to point the colormap to the right indices GR.setcolormap(1000 + GR.COLORMAP_COOLWARM) + # calculate the colorbar limits once for a subplot + clims = get_clims(sp) + for (idx, series) in enumerate(series_list(sp)) st = series[:seriestype] @@ -947,16 +965,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) zmin, zmax = extrema(series[:marker_z]) GR.setspace(zmin, zmax, 0, 90) end - gr_draw_markers(series, x, y) + gr_draw_markers(series, x, y, clims) end elseif st == :contour - zmin, zmax = gr_lims(zaxis, false) - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (zmin = clims[1]) - isfinite(clims[2]) && (zmax = clims[2]) - end + zmin, zmax = clims GR.setspace(zmin, zmax, 0, 90) if typeof(series[:levels]) <: Array h = series[:levels] @@ -995,12 +1008,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :heatmap xmin, xmax, ymin, ymax = xy_lims - zmin, zmax = gr_lims(zaxis, true) - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (zmin = clims[1]) - isfinite(clims[2]) && (zmax = clims[2]) - end + zmin, zmax = clims GR.setspace(zmin, zmax, 0, 90) grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad() colors = [grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)] for zi=z] @@ -1010,7 +1018,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, red(c) * 255) ), colors) w, h = length(x), length(y) GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) - cmap && gr_colorbar(sp) + cmap && gr_colorbar(sp, clims) elseif st in (:path3d, :scatter3d) # draw path @@ -1024,7 +1032,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw markers if st == :scatter3d || series[:markershape] != :none x2, y2 = unzip(map(GR.wc3towc, x, y, z)) - gr_draw_markers(series, x2, y2) + gr_draw_markers(series, x2, y2, clims) end # TODO: replace with pie recipe diff --git a/src/utils.jl b/src/utils.jl index 8c5986fc..ba81dd30 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -539,6 +539,28 @@ xlims(sp_idx::Int = 1) = xlims(current(), sp_idx) ylims(sp_idx::Int = 1) = ylims(current(), sp_idx) zlims(sp_idx::Int = 1) = zlims(current(), sp_idx) + +function get_clims(sp::Subplot) + zmin, zmax = Inf, -Inf + for series in series_list(sp) + for vals in (series[:z], series[:line_z], series[:marker_z]) + if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real) + zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...) + elseif (vals != nothing) && (eltype(vals) <: Real) + zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals)...) + end + end + end + clims = sp[:clims] + if is_2tuple(clims) + isfinite(clims[1]) && (zmin = clims[1]) + isfinite(clims[2]) && (zmax = clims[2]) + end + return zmin < zmax ? (zmin, zmax) : (0.0, 0.0) +end + +_update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) + # --------------------------------------------------------------- makekw(; kw...) = KW(kw) diff --git a/test/runtests.jl b/test/runtests.jl index 3f471735..671cfab3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,7 @@ include("imgcomp.jl") # don't actually show the plots srand(1234) default(show=false, reuse=true) -img_eps = isinteractive() ? 1e-2 : 10e-2 +img_eps = isinteractive() ? 1e-4 : 12e-2 @testset "GR" begin ENV["GKSwstype"] = "100" From a518796736c55da0bde04ee343094db4040df507 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 8 Sep 2017 23:38:43 +0200 Subject: [PATCH 347/720] reset runtests accuracy --- test/runtests.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/runtests.jl b/test/runtests.jl index 671cfab3..3f471735 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -5,7 +5,7 @@ include("imgcomp.jl") # don't actually show the plots srand(1234) default(show=false, reuse=true) -img_eps = isinteractive() ? 1e-4 : 12e-2 +img_eps = isinteractive() ? 1e-2 : 10e-2 @testset "GR" begin ENV["GKSwstype"] = "100" From 7dfa1ec984cd125933dbb454c781a0bfd7273903 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 9 Sep 2017 10:05:58 +0200 Subject: [PATCH 348/720] make GR use hascolorbar --- src/backends/gr.jl | 39 ++++++++++++++++----------------------- src/utils.jl | 13 +++++++++++++ 2 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c58e4356..ebd35f20 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -341,7 +341,7 @@ function gr_draw_markers(series::Series, x, y, clims) mz = normalize_zvals(series[:marker_z], clims) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_draw_markers(series, x, y, series[:markersize], mz) - if mz != nothing + if hascolorbar(series[:subplot]) GR.setscale(0) gr_colorbar(series[:subplot], clims) end @@ -447,25 +447,21 @@ end # add the colorbar function gr_colorbar(sp::Subplot) - if sp[:colorbar] != :none - gr_set_viewport_cmap(sp) - GR.colorbar() - gr_set_viewport_plotarea() - end + gr_set_viewport_cmap(sp) + GR.colorbar() + gr_set_viewport_plotarea() end function gr_colorbar(sp::Subplot, clims) - if sp[:colorbar] != :none - xmin, xmax = gr_xy_axislims(sp)[1:2] - gr_set_viewport_cmap(sp) - l = zeros(Int32, 1, 256) - l[1,:] = Int[round(Int, _i) for _i in linspace(1000, 1255, 256)] - GR.setwindow(xmin, xmax, clims[1], clims[2]) - GR.cellarray(xmin, xmax, clims[2], clims[1], 1, length(l), l) - ztick = 0.5 * GR.tick(clims[1], clims[2]) - GR.axes(0, ztick, xmax, clims[1], 0, 1, 0.005) - gr_set_viewport_plotarea() - end + xmin, xmax = gr_xy_axislims(sp)[1:2] + gr_set_viewport_cmap(sp) + l = zeros(Int32, 1, 256) + l[1,:] = Int[round(Int, _i) for _i in linspace(1000, 1255, 256)] + GR.setwindow(xmin, xmax, clims[1], clims[2]) + GR.cellarray(xmin, xmax, clims[2], clims[1], 1, length(l), l) + ztick = 0.5 * GR.tick(clims[1], clims[2]) + GR.axes(0, ztick, xmax, clims[1], 0, 1, 0.005) + gr_set_viewport_plotarea() end gr_view_xcenter() = 0.5 * (viewport_plotarea[1] + viewport_plotarea[2]) @@ -677,14 +673,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # reduced from before... set some flags based on the series in this subplot # TODO: can these be generic flags? outside_ticks = false - cmap = false + cmap = hascolorbar(sp) draw_axes = sp[:framestyle] != :none # axes_2d = true for series in series_list(sp) st = series[:seriestype] - if st in (:contour, :surface, :heatmap) || series[:marker_z] != nothing - cmap = true - end if st == :pie draw_axes = false end @@ -698,7 +691,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end end - if cmap && sp[:colorbar] != :none + if cmap # note: add extra midpadding on the right for the colorbar viewport_plotarea[2] -= 0.1 end @@ -983,7 +976,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end # create the colorbar of contour levels - if sp[:colorbar] != :none + if cmap gr_set_viewport_cmap(sp) l = round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) diff --git a/src/utils.jl b/src/utils.jl index ba81dd30..317c9da2 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -561,6 +561,19 @@ end _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) +function hascolorbar(sp::Subplot) + cbar = sp[:colorbar] + hascbar = false + if cbar != :none + for series in series_list(sp) + if series[:seriestype] in (:heatmap, :contour, :surface) || series[:marker_z] != nothing || series[:line_z] != nothing + hascbar = true + end + end + end + hascbar +end + # --------------------------------------------------------------- makekw(; kw...) = KW(kw) From 518fba759fb249598d2171d3f72857d4cf214404 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 9 Sep 2017 11:21:39 +0200 Subject: [PATCH 349/720] only one colorbar per subplot in pyplot --- src/backends/pyplot.jl | 97 +++++++++++++++--------------------------- src/utils.jl | 15 ++++++- 2 files changed, 48 insertions(+), 64 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index e2db4322..3bdb52a4 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -444,11 +444,16 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) xyargs = (st in _3dTypes ? (x,y,z) : (x,y)) # handle zcolor and get c/cmap - extrakw = KW() + needs_colorbar = hascolorbar(sp) + extrakw = if needs_colorbar + vmin, vmax = get_clims(sp) + KW(:vmin => vmin, :vmax => vmax) + else + KW() + end # holds references to any python object representing the matplotlib series handles = [] - needs_colorbar = false discrete_colorbar_values = nothing @@ -495,11 +500,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :linewidth => py_dpi_scale(plt, series[:linewidth]), :linestyle => py_linestyle(st, series[:linestyle]) ) - clims = sp[:clims] - if is_2tuple(clims) - extrakw = KW() - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) + if needs_colorbar kw[:norm] = pycolors["Normalize"](; extrakw...) end lz = collect(series[:line_z]) @@ -563,18 +564,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if series[:markershape] != :none && st in (:path, :scatter, :path3d, :scatter3d, :steppre, :steppost, :bar) - extrakw = KW() if series[:marker_z] == nothing extrakw[:c] = py_color_fix(py_markercolor(series), x) else extrakw[:c] = convert(Vector{Float64}, series[:marker_z]) extrakw[:cmap] = py_markercolormap(series) - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - end - needs_colorbar = true end xyargs = if st == :bar && !isvertical(series) (y, x) @@ -624,11 +618,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end if st == :hexbin - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - end handle = ax[:hexbin](x, y; label = series[:label], zorder = series[:series_plotindex], @@ -646,12 +635,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) z = transpose_z(series, z.surf) needs_colorbar = true - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - end - if st == :contour3d extrakw[:extend3d] = true end @@ -688,11 +671,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end z = transpose_z(series, z) if st == :surface - clims = sp[:clims] - if is_2tuple(clims) - isfinite(clims[1]) && (extrakw[:vmin] = clims[1]) - isfinite(clims[2]) && (extrakw[:vmax] = clims[2]) - end 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)) @@ -727,10 +705,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end end - # no colorbar if we are creating a surface LightSource - if haskey(extrakw, :facecolors) - needs_colorbar = false - end elseif typeof(z) <: AbstractVector # tri-surface plot (http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html#tri-surface-plots) @@ -788,11 +762,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) discrete_colorbar_values = dvals end - clims = sp[:clims] - zmin, zmax = ignorenan_extrema(z) - extrakw[:vmin] = (is_2tuple(clims) && isfinite(clims[1])) ? clims[1] : zmin - extrakw[:vmax] = (is_2tuple(clims) && isfinite(clims[2])) ? clims[2] : zmax - handle = ax[:pcolormesh](x, y, py_mask_nans(z); label = series[:label], zorder = series[:series_plotindex], @@ -844,30 +813,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # # smoothing # handleSmooth(plt, ax, series, series[:smooth]) - # add the colorbar legend - if needs_colorbar && sp[:colorbar] != :none - # add keyword args for a discrete colorbar - handle = handles[end] - kw = KW() - if discrete_colorbar_values != nothing - locator, formatter = get_locator_and_formatter(discrete_colorbar_values) - # kw[:values] = 1:length(discrete_colorbar_values) - kw[:values] = sp[:zaxis][:continuous_values] - kw[:ticks] = locator - kw[:format] = formatter - kw[:boundaries] = vcat(0, kw[:values] + 0.5) - end - - # create and store the colorbar object (handle) and the axis that it is drawn on. - # note: the colorbar axis is positioned independently from the subplot axis - fig = plt.o - cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) - cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title]) - sp.attr[:cbar_handle] = cb - sp.attr[:cbar_ax] = cbax - end - # handle area filling fillrange = series[:fillrange] if fillrange != nothing && st != :contour @@ -1042,6 +987,32 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # ax[:set_title](sp[:title], loc = loc) end + # add the colorbar legend + if hascolorbar(sp) + # add keyword args for a discrete colorbar + slist = series_list(sp) + colorbar_series = slist[findfirst(hascolorbar.(slist))] + handle = colorbar_series[:serieshandle][end] + kw = KW() + if !isempty(sp[:zaxis][:discrete_values]) && colorbar_series[:seriestype] == :heatmap + locator, formatter = get_locator_and_formatter(sp[:zaxis][:discrete_values]) + # kw[:values] = 1:length(sp[:zaxis][:discrete_values]) + kw[:values] = sp[:zaxis][:continuous_values] + kw[:ticks] = locator + kw[:format] = formatter + kw[:boundaries] = vcat(0, kw[:values] + 0.5) + end + + # create and store the colorbar object (handle) and the axis that it is drawn on. + # note: the colorbar axis is positioned independently from the subplot axis + fig = plt.o + cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) + cb = fig[:colorbar](handle; cax = cbax, kw...) + cb[:set_label](sp[:colorbar_title]) + sp.attr[:cbar_handle] = cb + sp.attr[:cbar_ax] = cbax + end + # framestyle if !ispolar(sp) && !is3d(sp) if sp[:framestyle] == :semi diff --git a/src/utils.jl b/src/utils.jl index 317c9da2..bc13d191 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -561,12 +561,25 @@ end _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) +function hascolorbar(series::Series) + st = series[:seriestype] + hascbar = st in (:heatmap, :contour) + if series[:marker_z] != nothing || series[:line_z] != nothing + hascbar = true + end + # no colorbar if we are creating a surface LightSource + if xor(st == :surface, series[:fill_z] != nothing) + hascbar = true + end + return hascbar +end + function hascolorbar(sp::Subplot) cbar = sp[:colorbar] hascbar = false if cbar != :none for series in series_list(sp) - if series[:seriestype] in (:heatmap, :contour, :surface) || series[:marker_z] != nothing || series[:line_z] != nothing + if hascolorbar(series) hascbar = true end end From dc9a0441415c615b3e0cfde98b9eac32e90a0a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Asbj=C3=B8rn=20Nilsen=20Riseth?= Date: Tue, 12 Sep 2017 16:08:32 +0100 Subject: [PATCH 350/720] Use show instead of writemime for eps --- src/output.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index 41cc9d0c..f26b6720 100644 --- a/src/output.jl +++ b/src/output.jl @@ -39,7 +39,7 @@ ps(fn::AbstractString) = ps(current(), fn) function eps(plt::Plot, fn::AbstractString) fn = addExtension(fn, "eps") io = open(fn, "w") - writemime(io, MIME("image/eps"), plt) + show(io, MIME("image/eps"), plt) close(io) end eps(fn::AbstractString) = eps(current(), fn) From f43f2956f5cdf0d064bc3fb2b1376afbd054febe Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 15 Sep 2017 18:39:56 +0200 Subject: [PATCH 351/720] activate clims for inactive colorbar --- 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 3bdb52a4..e86d71e4 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -445,7 +445,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # handle zcolor and get c/cmap needs_colorbar = hascolorbar(sp) - extrakw = if needs_colorbar + extrakw = if needs_colorbar || is_2tuple(sp[:clims]) vmin, vmax = get_clims(sp) KW(:vmin => vmin, :vmax => vmax) else From 9eae2ad76b48fb0d1d99b0c25f85f1cc5a58d039 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 15 Sep 2017 18:42:38 +0200 Subject: [PATCH 352/720] remove unnecessary setting of needs_colorbar --- src/backends/pyplot.jl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index e86d71e4..8d0d310e 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -530,7 +530,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) lc end push!(handles, handle) - needs_colorbar = true end a = series[:arrow] @@ -628,12 +627,10 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) extrakw... ) push!(handles, handle) - needs_colorbar = true end if st in (:contour, :contour3d) z = transpose_z(series, z.surf) - needs_colorbar = true if st == :contour3d extrakw[:extend3d] = true @@ -678,7 +675,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) else extrakw[:cmap] = py_fillcolormap(series) end - needs_colorbar = true end handle = ax[st == :surface ? :plot_surface : :plot_wireframe](x, y, z; label = series[:label], @@ -701,7 +697,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) offset = (zdir == "y" ? ignorenan_maximum : ignorenan_minimum)(mat) # where to draw the contour plane ) push!(handles, handle) - needs_colorbar = true end end @@ -722,7 +717,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) extrakw... ) push!(handles, handle) - needs_colorbar = true else error("Unsupported z type $(typeof(z)) for seriestype=$st") end @@ -770,7 +764,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) extrakw... ) push!(handles, handle) - needs_colorbar = true end if st == :shape From 7ba128db712e195434cf4caf55add84eb6461215 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 17 Sep 2017 19:14:44 +0200 Subject: [PATCH 353/720] fix marker_z for plotly --- src/backends/plotly.jl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8da2be0f..6753787e 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -575,14 +575,18 @@ function plotly_series(plt::Plot, series::Series) ) # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient - d_out[:marker][:color] = if series[:marker_z] == nothing - rgba_string(series[:markercolor]) + if series[:marker_z] == nothing + d_out[:marker][:color] = rgba_string(series[:markercolor]) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) - grad = as_gradient(series[:markercolor], series[:markeralpha]) - zmin, zmax = ignorenan_extrema(series[:marker_z]) - zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) - [rgba_string(grad[(zi - zmin) / zrange]) for zi in series[:marker_z]] + # grad = as_gradient(series[:markercolor], series[:markeralpha]) + cmin, cmax = get_clims(sp) + # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) + d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in series[:marker_z]] + d_out[:marker][:cmin] = cmin + d_out[:marker][:cmax] = cmax + d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha]) + d_out[:marker][:showscale] = hascolorbar(sp) end end From bdfc4636f018232239c3d00a81e809bd8842d4f1 Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Tue, 19 Sep 2017 23:22:36 +0100 Subject: [PATCH 354/720] Fix for wrong setting of logscale for values below 1e-16 --- 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 8d0d310e..d9f36015 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -903,7 +903,7 @@ function py_set_scale(ax, axis::Axis) elseif scale == :log10 10 end - kw[Symbol(:linthresh,letter)] = NaNMath.max(1e-16, py_compute_axis_minval(axis)) + kw[Symbol(:linthresh,letter)] = NaNMath.min(1e-16, py_compute_axis_minval(axis)) "symlog" end func(arg; kw...) From b6dca5e9b1b4e5b8b3ec5247bf7181045661e245 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 22 Sep 2017 20:27:16 +0200 Subject: [PATCH 355/720] Allow plotting empty Vector{Any} --- src/series.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/series.jl b/src/series.jl index 12944a77..6b5b0198 100644 --- a/src/series.jl +++ b/src/series.jl @@ -174,6 +174,7 @@ _apply_type_recipe(d, v) = RecipesBase.apply_recipe(d, typeof(v), v)[1].args[1] # This sort of recipe should return a pair of functions... one to convert to number, # and one to format tick values. function _apply_type_recipe(d, v::AbstractArray) + isempty(v) && return Float64[] args = RecipesBase.apply_recipe(d, typeof(v[1]), v[1])[1].args if length(args) == 2 && typeof(args[1]) <: Function && typeof(args[2]) <: Function numfunc, formatter = args From 8b4edae35858a12533332719ce568aab4693f7f9 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 24 Sep 2017 20:52:02 +0200 Subject: [PATCH 356/720] implement line_z for GR --- src/backends/gr.jl | 10 +++++++--- src/utils.jl | 11 +++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ebd35f20..a3d86d9c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -22,7 +22,7 @@ const _gr_attr = merge_with_base_supported([ :tickfont, :guidefont, :legendfont, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, - :marker_z, :levels, + :line_z, :marker_z, :levels, :ribbon, :quiver, :orientation, :overwrite_figure, @@ -896,6 +896,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_gradient(series[:fillcolor]) #, series[:fillalpha]) elseif series[:marker_z] != nothing series[:markercolor] = gr_set_gradient(series[:markercolor]) + elseif series[:line_z] != nothing + series[:linecolor] = gr_set_gradient(series[:linecolor]) end GR.savestate() @@ -947,9 +949,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st == :path - gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x, y; arrowside = arrowside) + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + cmap && gr_colorbar(sp, clims) end end @@ -1169,7 +1173,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) diff --git a/src/utils.jl b/src/utils.jl index bc13d191..38bb2b5a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -587,6 +587,17 @@ function hascolorbar(sp::Subplot) hascbar end +function get_linecolor(sp::Subplot, series::Series) + lc = series[:linecolor] + if series[:line_z] == nothing + lc + else + cmin, cmax = get_clims(sp) + grad = isa(lc, ColorGradient) ? lc : cgrad() + grad[clamp((series[:line_z] - cmin) / (cmax -cmin), 0, 1)] + end +end + # --------------------------------------------------------------- makekw(; kw...) = KW(kw) From 337a107168b6739d3e4bd0c35d201f63f6346110 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 25 Sep 2017 17:22:13 +0200 Subject: [PATCH 357/720] different colors for different line segments in GR --- src/backends/gr.jl | 10 ++++++---- src/utils.jl | 9 +++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index a3d86d9c..60fdba5b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -949,9 +949,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st == :path - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) - arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none - gr_polyline(x, y; arrowside = arrowside) + for (i,rng) in enumerate(iter_segments(series[:x], series[:y])) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) + arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none + gr_polyline(series[:x][rng], series[:y][rng]; arrowside = arrowside) + end gr_set_line(1, :solid, yaxis[:foreground_color_axis]) cmap && gr_colorbar(sp, clims) end @@ -1173,7 +1175,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, 1)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) diff --git a/src/utils.jl b/src/utils.jl index 38bb2b5a..f9a6cb0c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -587,14 +587,15 @@ function hascolorbar(sp::Subplot) hascbar end -function get_linecolor(sp::Subplot, series::Series) +function get_linecolor(sp::Subplot, series::Series, i::Int) lc = series[:linecolor] - if series[:line_z] == nothing - lc + lz = series[:line_z] + if lz == nothing + _cycle(lc, i) else cmin, cmax = get_clims(sp) grad = isa(lc, ColorGradient) ? lc : cgrad() - grad[clamp((series[:line_z] - cmin) / (cmax -cmin), 0, 1)] + grad[clamp((_cycle(lz, i) - cmin) / (cmax -cmin), 0, 1)] end end From c6b7ff6c7585fdc0bb344cfe8cb6ca27c96a4c1b Mon Sep 17 00:00:00 2001 From: AnkurD Date: Tue, 26 Sep 2017 17:16:03 +0900 Subject: [PATCH 358/720] Colorbar takes font style from Y Axis --- src/backends/pyplot.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d9f36015..ff2853f2 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -999,9 +999,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # create and store the colorbar object (handle) and the axis that it is drawn on. # note: the colorbar axis is positioned independently from the subplot axis fig = plt.o - cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) - cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title]) + cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) + cb = fig[:colorbar](handle; cax = cbax, kw...) + cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefont].pointsize),family=sp[:yaxis][:guidefont].family) + for lab in cb[:ax][:yaxis][:get_ticklabels]() + lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) + lab[:set_family](sp[:yaxis][:tickfont].family) + end sp.attr[:cbar_handle] = cb sp.attr[:cbar_ax] = cbax end From 5b3c41bd774f96b6e19aedad119c53df2d77cfb4 Mon Sep 17 00:00:00 2001 From: AnkurD Date: Tue, 26 Sep 2017 17:22:17 +0900 Subject: [PATCH 359/720] Colorbar takes font style from Y Axis --- src/backends/pyplot.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ff2853f2..f5ffbc07 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -999,13 +999,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # create and store the colorbar object (handle) and the axis that it is drawn on. # note: the colorbar axis is positioned independently from the subplot axis fig = plt.o - cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) - cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefont].pointsize),family=sp[:yaxis][:guidefont].family) - for lab in cb[:ax][:yaxis][:get_ticklabels]() - lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) - lab[:set_family](sp[:yaxis][:tickfont].family) - end + cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) + cb = fig[:colorbar](handle; cax = cbax, kw...) + cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefont].pointsize),family=sp[:yaxis][:guidefont].family) + for lab in cb[:ax][:yaxis][:get_ticklabels]() + lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) + lab[:set_family](sp[:yaxis][:tickfont].family) + end sp.attr[:cbar_handle] = cb sp.attr[:cbar_ax] = cbax end From 5f8486536561746b73823065ac033896ed220082 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 26 Sep 2017 16:58:46 +0200 Subject: [PATCH 360/720] implement fill_z and line_z for GR --- src/args.jl | 5 +++- src/backends/gr.jl | 60 ++++++++++++++++++++++++++++------------------ src/utils.jl | 27 +++++++++++++++++---- 3 files changed, 63 insertions(+), 29 deletions(-) diff --git a/src/args.jl b/src/args.jl index caa2f7b7..0e9f4569 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1371,13 +1371,16 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) getSeriesRGBColor(d[:markerstrokecolor], d[:markerstrokealpha], sp, plotIndex) end - # if marker_z or line_z are set, ensure we have a gradient + # if marker_z, fill_z or line_z are set, ensure we have a gradient if d[:marker_z] != nothing ensure_gradient!(d, :markercolor, :markeralpha) end if d[:line_z] != nothing ensure_gradient!(d, :linecolor, :linealpha) end + if d[:fill_z] != nothing + ensure_gradient!(d, :fillcolor, :fillalpha) + end # scatter plots don't have a line, but must have a shape if d[:seriestype] in (:scatter, :scatterbins, :scatterhist, :scatter3d) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 60fdba5b..e6c68b41 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -22,7 +22,7 @@ const _gr_attr = merge_with_base_supported([ :tickfont, :guidefont, :legendfont, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, - :line_z, :marker_z, :levels, + :fill_z, :line_z, :marker_z, :levels, :ribbon, :quiver, :orientation, :overwrite_figure, @@ -898,6 +898,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) series[:markercolor] = gr_set_gradient(series[:markercolor]) elseif series[:line_z] != nothing series[:linecolor] = gr_set_gradient(series[:linecolor]) + elseif series[:fill_z] != nothing + series[:fillcolor] = gr_set_gradient(series[:fillcolor]) end GR.savestate() @@ -936,23 +938,26 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if frng != nothing GR.setfillintstyle(GR.INTSTYLE_SOLID) fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng)) - for (i,rng) in enumerate(iter_segments(series[:x], series[:y])) - if length(rng) > 1 - gr_set_fillcolor(_cycle(series[:fillcolor], i)) - fx = _cycle(x, vcat(rng, reverse(rng))) - fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) - # @show i rng fx fy - GR.fillarea(fx, fy) - end + for i in 1:length(x) - 1 + gr_set_fillcolor(get_fillcolor(sp, series, i)) + xseg = _cycle(x, [i, i+1, i+1, i]) + yseg = [_cycle(fr_from, [i, i+1]); _cycle(fr_to, [i+1, i])] + GR.settransparency(series[:fillalpha]) + GR.fillarea(xseg, yseg) end + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + GR.settransparency(1) + cmap && gr_colorbar(sp, clims) end # draw the line(s) if st == :path - for (i,rng) in enumerate(iter_segments(series[:x], series[:y])) + for i in 1:length(x) - 1 + xseg = x[i:(i + 1)] + yseg = y[i:(i + 1)] gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) - arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none - gr_polyline(series[:x][rng], series[:y][rng]; arrowside = arrowside) + arrowside = (i == length(y) - 1) && isa(series[:arrow], Arrow) ? series[:arrow].side : :none + gr_polyline(xseg, yseg; arrowside = arrowside) end gr_set_line(1, :solid, yaxis[:foreground_color_axis]) cmap && gr_colorbar(sp, clims) @@ -1022,10 +1027,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st in (:path3d, :scatter3d) # draw path if st == :path3d - if length(x) > 1 - gr_set_line(series[:linewidth], series[:linestyle], series[:linecolor]) #, series[:linealpha]) - GR.polyline3d(x, y, z) + for i in 1:length(x) - 1 + xseg = x[i:(i + 1)] + yseg = y[i:(i + 1)] + zseg = z[i:(i + 1)] + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) + GR.polyline3d(xseg, yseg, zseg) end + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + cmap && gr_colorbar(sp, clims) end # draw markers @@ -1083,22 +1093,26 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.selntran(1) elseif st == :shape - for (i,rng) in enumerate(iter_segments(series[:x], series[:y])) + for (i,rng) in enumerate(iter_segments(x, y)) if length(rng) > 1 # connect to the beginning rng = vcat(rng, rng[1]) # get the segments - x, y = series[:x][rng], series[:y][rng] + xseg, yseg = x[rng], y[rng] + @show xseg + @show yseg # draw the interior - gr_set_fill(_cycle(series[:fillcolor], i)) - GR.fillarea(x, y) + gr_set_fill(get_fillcolor(sp, series, i)) + GR.fillarea(xseg, yseg) # draw the shapes - gr_set_line(series[:linewidth], :solid, _cycle(series[:linecolor], i)) - GR.polyline(x, y) + gr_set_line(series[:linewidth], :solid, get_linecolor(sp, series, i)) + GR.polyline(xseg, yseg) end + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + cmap && gr_colorbar(sp, clims) end @@ -1175,10 +1189,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, 1)) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing - gr_set_fill(series[:fillcolor]) #, series[:fillalpha]) + gr_set_fill(get_fillcolor(sp, series)) #, series[:fillalpha]) l, r = xpos-0.07, xpos-0.01 b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] diff --git a/src/utils.jl b/src/utils.jl index f9a6cb0c..65142bfc 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -543,7 +543,7 @@ zlims(sp_idx::Int = 1) = zlims(current(), sp_idx) function get_clims(sp::Subplot) zmin, zmax = Inf, -Inf for series in series_list(sp) - for vals in (series[:z], series[:line_z], series[:marker_z]) + for vals in (series[:z], series[:line_z], series[:marker_z], series[:fill_z]) if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real) zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...) elseif (vals != nothing) && (eltype(vals) <: Real) @@ -564,7 +564,7 @@ _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) function hascolorbar(series::Series) st = series[:seriestype] hascbar = st in (:heatmap, :contour) - if series[:marker_z] != nothing || series[:line_z] != nothing + if series[:marker_z] != nothing || series[:line_z] != nothing || series[:fill_z] != nothing hascbar = true end # no colorbar if we are creating a surface LightSource @@ -587,15 +587,32 @@ function hascolorbar(sp::Subplot) hascbar end -function get_linecolor(sp::Subplot, series::Series, i::Int) +function get_linecolor(sp::Subplot, series::Series, i::Int = 1) lc = series[:linecolor] lz = series[:line_z] if lz == nothing - _cycle(lc, i) + isa(lc, ColorGradient) ? lc : _cycle(lc, i) else cmin, cmax = get_clims(sp) grad = isa(lc, ColorGradient) ? lc : cgrad() - grad[clamp((_cycle(lz, i) - cmin) / (cmax -cmin), 0, 1)] + grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)] + end +end + +function get_fillcolor(sp::Subplot, series::Series, i::Int = 1) + fc = series[:fillcolor] + fz = series[:fill_z] + lz = series[:line_z] + if fz == nothing && lz == nothing + isa(fc, ColorGradient) ? fc : _cycle(fc, i) + else + cmin, cmax = get_clims(sp) + grad = isa(fc, ColorGradient) ? fc : cgrad() + if fz != nothing + grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)] + elseif lz != nothing + grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)] + end end end From ea6ab46a13bd1068dc2b0692bd76eedb7b449b6c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 26 Sep 2017 17:18:35 +0200 Subject: [PATCH 361/720] fix fill_z for shapes (draw colorbar once) --- src/backends/gr.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e6c68b41..e2054a90 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1100,8 +1100,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # get the segments xseg, yseg = x[rng], y[rng] - @show xseg - @show yseg # draw the interior gr_set_fill(get_fillcolor(sp, series, i)) @@ -1111,9 +1109,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_line(series[:linewidth], :solid, get_linecolor(sp, series, i)) GR.polyline(xseg, yseg) end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - cmap && gr_colorbar(sp, clims) end + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + cmap && gr_colorbar(sp, clims) elseif st == :image From 9eac6a1db00b66fa03c254107e61eccc32f42f1b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 26 Sep 2017 17:40:54 +0200 Subject: [PATCH 362/720] fix fillalpha --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e2054a90..09fb7270 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -942,7 +942,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_fillcolor(get_fillcolor(sp, series, i)) xseg = _cycle(x, [i, i+1, i+1, i]) yseg = [_cycle(fr_from, [i, i+1]); _cycle(fr_to, [i+1, i])] - GR.settransparency(series[:fillalpha]) + series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) GR.fillarea(xseg, yseg) end gr_set_line(1, :solid, yaxis[:foreground_color_axis]) From b73ea55bbde6bfc5bd4f21e102b04051e423f4fb Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 27 Sep 2017 13:53:06 +0200 Subject: [PATCH 363/720] implement tick_direction for GR, PyPlot, Plotly and GLVisualize --- src/arg_desc.jl | 1 + src/args.jl | 3 ++- src/axes.jl | 18 ++++++++++-------- src/backends/gr.jl | 4 ++-- src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 1 + 6 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 8634eabb..88bc8cf8 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -115,4 +115,5 @@ const _arg_desc = KW( :gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.", :gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", :gridlinewidth => "Number. Width of the grid lines (in pixels)", +:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`" ) diff --git a/src/args.jl b/src/args.jl index 0e9f4569..2ceeaa93 100644 --- a/src/args.jl +++ b/src/args.jl @@ -322,6 +322,7 @@ const _axis_defaults = KW( :gridalpha => 0.1, :gridstyle => :solid, :gridlinewidth => 0.5, + :tick_direction => :in, ) const _suppress_warnings = Set{Symbol}([ @@ -511,7 +512,7 @@ add_aliases(:stride, :wirefame_stride, :surface_stride, :surf_str, :str) add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, :grid_lw) add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) - +add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor) # add all pluralized forms to the _keyAliases dict for arg in keys(_series_defaults) diff --git a/src/axes.jl b/src/axes.jl index 61370a27..7e628f10 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -530,13 +530,14 @@ function axis_drawing_info(sp::Subplot) if !(xaxis[:ticks] in (nothing, false)) f = scalefunc(yaxis[:scale]) invf = invscalefunc(yaxis[:scale]) - t1 = invf(f(ymin) + 0.015*(f(ymax)-f(ymin))) - t2 = invf(f(ymax) - 0.015*(f(ymax)-f(ymin))) - t3 = invf(f(0) - 0.015*(f(ymax)-f(ymin))) + ticks_in = xaxis[:tick_direction] == :out ? -1 : 1 + t1 = invf(f(ymin) + 0.013 * (f(ymax) - f(ymin)) * ticks_in) + t2 = invf(f(ymax) - 0.013 * (f(ymax) - f(ymin)) * ticks_in) + t3 = invf(f(0) + 0.013 * (f(ymax) - f(ymin)) * ticks_in) for xtick in xticks[1] tick_start, tick_stop = if sp[:framestyle] == :origin - (0, xaxis[:mirror] ? -t3 : t3) + (0, t3) else xaxis[:mirror] ? (ymax, t2) : (ymin, t1) end @@ -560,13 +561,14 @@ function axis_drawing_info(sp::Subplot) if !(yaxis[:ticks] in (nothing, false)) f = scalefunc(xaxis[:scale]) invf = invscalefunc(xaxis[:scale]) - t1 = invf(f(xmin) + 0.015*(f(xmax)-f(xmin))) - t2 = invf(f(xmax) - 0.015*(f(xmax)-f(xmin))) - t3 = invf(f(0) - 0.015*(f(xmax)-f(xmin))) + ticks_in = yaxis[:tick_direction] == :out ? -1 : 1 + t1 = invf(f(xmin) + 0.013 * (f(xmax) - f(xmin)) * ticks_in) + t2 = invf(f(xmax) - 0.013 * (f(xmax) - f(xmin)) * ticks_in) + t3 = invf(f(0) + 0.013 * (f(xmax) - f(xmin)) * ticks_in) for ytick in yticks[1] tick_start, tick_stop = if sp[:framestyle] == :origin - (0, yaxis[:mirror] ? -t3 : t3) + (0, t3) else yaxis[:mirror] ? (xmax, t2) : (xmin, t1) end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 09fb7270..b1680c20 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -827,7 +827,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3, string(dv)) + gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv)) end end @@ -838,7 +838,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi - gr_text(xi + (mirror ? 1 : -1) * 1e-2, yi, string(dv)) + gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv)) end end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 6753787e..02236e04 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -235,7 +235,7 @@ function plotly_axis(axis::Axis, sp::Subplot) :zerolinecolor => rgba_string(axis[:foreground_color_axis]), :showline => framestyle in (:box, :axes), :linecolor => rgba_string(plot_color(axis[:foreground_color_axis])), - :ticks => "inside", + :ticks => axis[:tick_direction] == :out ? "outside" : "inside", :mirror => framestyle == :box, ) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d9f36015..27f28e18 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1052,6 +1052,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ticks[2][ticks[1] .== 0] = "" end py_set_ticks(ax, ticks, letter) + pyaxis[:set_tick_params](direction = axis[:tick_direction] == :out ? "out" : "in") ax[Symbol("set_", letter, "label")](axis[:guide]) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() From 350237a7740fddb100ca7ab7cef0c27a8d32bc0f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 27 Sep 2017 13:56:12 +0200 Subject: [PATCH 364/720] add tick_direction to supported arguments --- src/backends/glvisualize.jl | 1 + src/backends/gr.jl | 1 + src/backends/plotly.jl | 1 + src/backends/pyplot.jl | 1 + 4 files changed, 4 insertions(+) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f9c01f29..1bdb79df 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -41,6 +41,7 @@ const _glvisualize_attr = merge_with_base_supported([ :dpi, :hover, :framestyle, + :tick_direction, ]) const _glvisualize_seriestype = [ :path, :shape, diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b1680c20..fcd93547 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -33,6 +33,7 @@ const _gr_attr = merge_with_base_supported([ :bar_width, :arrow, :framestyle, + :tick_direction, ]) const _gr_seriestype = [ :path, :scatter, diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 02236e04..1dd9060a 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -34,6 +34,7 @@ const _plotly_attr = merge_with_base_supported([ :bar_width, :clims, :framestyle, + :tick_direction, ]) const _plotly_seriestype = [ diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 27f28e18..ea0ba6c7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -34,6 +34,7 @@ const _pyplot_attr = merge_with_base_supported([ :colorbar_title, :stride, :framestyle, + :tick_direction, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, From 69fa9e7b1034c47a0978cb85b92a0deb519300d6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 27 Sep 2017 17:07:09 +0200 Subject: [PATCH 365/720] implement tick_direction for PGFPlots --- src/backends/pgfplots.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 30169147..046a4def 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -31,6 +31,7 @@ const _pgfplots_attr = merge_with_base_supported([ # :normalize, :weights, :contours, :aspect_ratio, # :match_dimensions, + :tick_direction, ]) const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] @@ -283,6 +284,7 @@ function pgf_axis(sp::Subplot, letter) ticks = get_ticks(axis) push!(style, string(letter, "tick = {", join(ticks[1],","), "}")) push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) + push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside"))) end # return the style list and KW args From 6c84624d713bfdc0d939508f49ac71fdf76984d9 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 27 Sep 2017 23:22:55 +0200 Subject: [PATCH 366/720] fix pgfplots --- 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 046a4def..97d68421 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -280,7 +280,7 @@ function pgf_axis(sp::Subplot, letter) kw[Symbol(letter,:max)] = lims[2] end - if !(axis[:ticks] in (nothing, false, :none, :auto)) + if !(axis[:ticks] in (nothing, false, :none)) ticks = get_ticks(axis) push!(style, string(letter, "tick = {", join(ticks[1],","), "}")) push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) From 1c048238777efe6ccbb623be329fa631451b1048 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 28 Sep 2017 00:07:58 +0200 Subject: [PATCH 367/720] reset tick size for gr and glvisualize --- src/axes.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 7e628f10..f989a8fb 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -531,9 +531,9 @@ function axis_drawing_info(sp::Subplot) f = scalefunc(yaxis[:scale]) invf = invscalefunc(yaxis[:scale]) ticks_in = xaxis[:tick_direction] == :out ? -1 : 1 - t1 = invf(f(ymin) + 0.013 * (f(ymax) - f(ymin)) * ticks_in) - t2 = invf(f(ymax) - 0.013 * (f(ymax) - f(ymin)) * ticks_in) - t3 = invf(f(0) + 0.013 * (f(ymax) - f(ymin)) * ticks_in) + t1 = invf(f(ymin) + 0.015 * (f(ymax) - f(ymin)) * ticks_in) + t2 = invf(f(ymax) - 0.015 * (f(ymax) - f(ymin)) * ticks_in) + t3 = invf(f(0) + 0.015 * (f(ymax) - f(ymin)) * ticks_in) for xtick in xticks[1] tick_start, tick_stop = if sp[:framestyle] == :origin @@ -562,9 +562,9 @@ function axis_drawing_info(sp::Subplot) f = scalefunc(xaxis[:scale]) invf = invscalefunc(xaxis[:scale]) ticks_in = yaxis[:tick_direction] == :out ? -1 : 1 - t1 = invf(f(xmin) + 0.013 * (f(xmax) - f(xmin)) * ticks_in) - t2 = invf(f(xmax) - 0.013 * (f(xmax) - f(xmin)) * ticks_in) - t3 = invf(f(0) + 0.013 * (f(xmax) - f(xmin)) * ticks_in) + t1 = invf(f(xmin) + 0.015 * (f(xmax) - f(xmin)) * ticks_in) + t2 = invf(f(xmax) - 0.015 * (f(xmax) - f(xmin)) * ticks_in) + t3 = invf(f(0) + 0.015 * (f(xmax) - f(xmin)) * ticks_in) for ytick in yticks[1] tick_start, tick_stop = if sp[:framestyle] == :origin From 650c1730c9149a3969beca7b476682d1c896b889 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 28 Sep 2017 23:32:25 +0200 Subject: [PATCH 368/720] Don't delete attr when `plot(::Plot)` - fix #1113 --- src/plot.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot.jl b/src/plot.jl index 3e6dd9a3..8968df8c 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -84,7 +84,7 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...) # TODO: replace this with proper processing from a merged user_attr KW # update plot args, first with existing plots, then override with d for p in plts - _update_plot_args(plt, p.attr) + _update_plot_args(plt, copy(p.attr)) plt.n += p.n end _update_plot_args(plt, d) From 4395718e0c5cfaa8053fc1261adbae65d564f52f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 29 Sep 2017 08:58:54 +0200 Subject: [PATCH 369/720] Try to find default x axis limits where function is defined --- src/series.jl | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index 6b5b0198..a22da163 100644 --- a/src/series.jl +++ b/src/series.jl @@ -363,11 +363,23 @@ end xmin, xmax = try axis_limits(plt[1][:xaxis]) catch - -5, 5 + tryrange(f, [-5,-1,0,0.01]), tryrange(f, [5,1,0.99]) end + f, xmin, xmax end +# try some intervals over which the function may be defined +function tryrange(F, vec) + for v in vec + try + tmp = F(v) + return v + catch + end + end + error("Function not defined over the given interval, $vec") +end # # # -------------------------------------------------------------------- # # 2 arguments From 07843c00d3a351a22989ff72df7b5fffc5b9fcf3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 29 Sep 2017 09:18:20 +0200 Subject: [PATCH 370/720] Add negative ranges --- src/series.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index a22da163..66518b78 100644 --- a/src/series.jl +++ b/src/series.jl @@ -363,9 +363,10 @@ end xmin, xmax = try axis_limits(plt[1][:xaxis]) catch - tryrange(f, [-5,-1,0,0.01]), tryrange(f, [5,1,0.99]) + xm = tryrange(f, [-5,-1,0,0.01]) + xm, tryrange(f, filter(x->x>xm, [5,1,0.99, 0, -0.01])) end - + f, xmin, xmax end From 18188516ec7c02994b57ae7e7ffff03c56edd189 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 29 Sep 2017 11:48:17 +0200 Subject: [PATCH 371/720] implement showaxis attribute for gr --- src/arg_desc.jl | 3 ++- src/args.jl | 22 ++++++++++++++-- src/axes.jl | 63 +++++++++++++++++++++++++++------------------- src/backends/gr.jl | 52 ++++++++++++++++++++++---------------- 4 files changed, 89 insertions(+), 51 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 88bc8cf8..ce7cde8b 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -115,5 +115,6 @@ const _arg_desc = KW( :gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.", :gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", :gridlinewidth => "Number. Width of the grid lines (in pixels)", -:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`" +:tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`", +:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`" ) diff --git a/src/args.jl b/src/args.jl index 2ceeaa93..83379dfd 100644 --- a/src/args.jl +++ b/src/args.jl @@ -170,8 +170,8 @@ const _scaleAliases = Dict{Symbol,Symbol}( const _allGridSyms = [:x, :y, :z, :xy, :xz, :yx, :yz, :zx, :zy, :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, - :all, :both, :on, - :none, :off,] + :all, :both, :on, :yes, + :none, :off, :no] const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing] hasgrid(arg::Void, letter) = false hasgrid(arg::Bool, letter) = arg @@ -185,6 +185,24 @@ function hasgrid(arg::Symbol, letter) end hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) +const _allShowaxisSyms = [:x, :y, :z, + :xy, :xz, :yx, :yz, :zx, :zy, + :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, + :all, :both, :on, :yes, + :none, :off, :no] +const _allShowaxisArgs = [_allGridSyms; string.(_allGridSyms)] +showaxis(arg::Void, letter) = false +showaxis(arg::Bool, letter) = arg +function hasgrid(arg::Symbol, letter) + if arg in _allGridSyms + arg in (:all, :both, :on, :yes) || contains(string(arg), string(letter)) + else + warn("Unknown showaxis argument $arg; $(Symbol(letter, :showaxis)) was set to `true` instead.") + true + end +end +showaxis(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) + const _allFramestyles = [:box, :semi, :axes, :origin, :zerolines, :grid, :none] const _framestyleAliases = Dict{Symbol, Symbol}( :frame => :box, diff --git a/src/axes.jl b/src/axes.jl index f989a8fb..6d06a261 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -70,6 +70,9 @@ function process_axis_arg!(d::KW, arg, letter = "") elseif arg == nothing d[Symbol(letter,:ticks)] = [] + elseif arg in _allShowaxisArgs + d[Symbol(letter,:showaxis)] = showaxis(arg, letter) + elseif typeof(arg) <: Number d[Symbol(letter,:rotation)] = arg @@ -517,16 +520,18 @@ function axis_drawing_info(sp::Subplot) if !(sp[:framestyle] == :none) # xaxis - sp[:framestyle] in (:grid, :origin, :zerolines) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis - if sp[:framestyle] in (:origin, :zerolines) - push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) - # don't show the 0 tick label for the origin framestyle - if sp[:framestyle] == :origin && length(xticks) > 1 - showticks = xticks[1] .!= 0 - xticks = (xticks[1][showticks], xticks[2][showticks]) + if xaxis[:showaxis] + sp[:framestyle] in (:grid, :origin, :zerolines) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis + if sp[:framestyle] in (:origin, :zerolines) + push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) + # don't show the 0 tick label for the origin framestyle + if sp[:framestyle] == :origin && length(xticks) > 1 + showticks = xticks[1] .!= 0 + xticks = (xticks[1][showticks], xticks[2][showticks]) + end end + sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine end - sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine if !(xaxis[:ticks] in (nothing, false)) f = scalefunc(yaxis[:scale]) invf = invscalefunc(yaxis[:scale]) @@ -536,28 +541,32 @@ function axis_drawing_info(sp::Subplot) t3 = invf(f(0) + 0.015 * (f(ymax) - f(ymin)) * ticks_in) for xtick in xticks[1] - tick_start, tick_stop = if sp[:framestyle] == :origin - (0, t3) - else - xaxis[:mirror] ? (ymax, t2) : (ymin, t1) + if xaxis[:showaxis] + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, t3) + else + xaxis[:mirror] ? (ymax, t2) : (ymin, t1) + end + push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick end - push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid end end # yaxis - sp[:framestyle] in (:grid, :origin, :zerolines) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis - if sp[:framestyle] in (:origin, :zerolines) - push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) - # don't show the 0 tick label for the origin framestyle - if sp[:framestyle] == :origin && length(yticks) > 1 - showticks = yticks[1] .!= 0 - yticks = (yticks[1][showticks], yticks[2][showticks]) + if yaxis[:showaxis] + sp[:framestyle] in (:grid, :origin, :zerolines) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis + if sp[:framestyle] in (:origin, :zerolines) + push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) + # don't show the 0 tick label for the origin framestyle + if sp[:framestyle] == :origin && length(yticks) > 1 + showticks = yticks[1] .!= 0 + yticks = (yticks[1][showticks], yticks[2][showticks]) + end end + sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine end - sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine if !(yaxis[:ticks] in (nothing, false)) f = scalefunc(xaxis[:scale]) invf = invscalefunc(xaxis[:scale]) @@ -567,12 +576,14 @@ function axis_drawing_info(sp::Subplot) t3 = invf(f(0) + 0.015 * (f(xmax) - f(xmin)) * ticks_in) for ytick in yticks[1] - tick_start, tick_stop = if sp[:framestyle] == :origin - (0, t3) - else - yaxis[:mirror] ? (xmax, t2) : (xmin, t1) + if yaxis[:showaxis] + tick_start, tick_stop = if sp[:framestyle] == :origin + (0, t3) + else + yaxis[:mirror] ? (xmax, t2) : (xmin, t1) + end + push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick end - push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index fcd93547..3bad3a0f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -793,35 +793,43 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.settransparency(1.0) # axis lines - gr_set_line(1, :solid, xaxis[:foreground_color_axis]) - GR.setclip(0) - gr_polyline(coords(xspine_segs)...) - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - GR.setclip(0) - gr_polyline(coords(yspine_segs)...) + if xaxis[:showaxis] + gr_set_line(1, :solid, xaxis[:foreground_color_axis]) + GR.setclip(0) + gr_polyline(coords(xspine_segs)...) + end + if yaxis[:showaxis] + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + GR.setclip(0) + gr_polyline(coords(yspine_segs)...) + end GR.setclip(1) # axis ticks - if sp[:framestyle] in (:zerolines, :grid) - gr_set_line(1, :solid, xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) - else - gr_set_line(1, :solid, xaxis[:foreground_color_axis]) + if xaxis[:showaxis] + if sp[:framestyle] in (:zerolines, :grid) + gr_set_line(1, :solid, xaxis[:foreground_color_grid]) + GR.settransparency(xaxis[:gridalpha]) + else + gr_set_line(1, :solid, xaxis[:foreground_color_axis]) + end + GR.setclip(0) + gr_polyline(coords(xtick_segs)...) end - GR.setclip(0) - gr_polyline(coords(xtick_segs)...) - if sp[:framestyle] in (:zerolines, :grid) - gr_set_line(1, :solid, yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) - else - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + if yaxis[:showaxis] + if sp[:framestyle] in (:zerolines, :grid) + gr_set_line(1, :solid, yaxis[:foreground_color_grid]) + GR.settransparency(yaxis[:gridalpha]) + else + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + end + GR.setclip(0) + gr_polyline(coords(ytick_segs)...) end - GR.setclip(0) - gr_polyline(coords(ytick_segs)...) GR.setclip(1) # tick marks - if !(xticks in (:none, nothing, false)) + if !(xticks in (:none, nothing, false)) && xaxis[:showaxis] # x labels flip, mirror = gr_set_xticks_font(sp) for (cv, dv) in zip(xticks...) @@ -832,7 +840,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end end - if !(yticks in (:none, nothing, false)) + if !(yticks in (:none, nothing, false)) && yaxis[:showaxis] # y labels flip, mirror = gr_set_yticks_font(sp) for (cv, dv) in zip(yticks...) From ee7a3b36864c4a94e2bc3e86dfb588cf9bc49540 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 29 Sep 2017 13:41:54 +0200 Subject: [PATCH 372/720] general axis fixes and improvemennts --- src/arg_desc.jl | 4 ++-- src/args.jl | 36 ++++++++++++++++++++++-------------- src/axes.jl | 4 ++-- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index ce7cde8b..ce24b8e0 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -110,11 +110,11 @@ const _arg_desc = KW( :foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.", :foreground_color_guide => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis guides (axis labels).", :mirror => "Bool. Switch the side of the tick labels (right or top).", -:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`", +:grid => "Bool, Symbol, String or `nothing`. Show the grid lines? `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`", :foreground_color_grid => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of grid lines.", :gridalpha => "Number in [0,1]. The alpha/opacity override for the grid lines.", :gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", :gridlinewidth => "Number. Width of the grid lines (in pixels)", :tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`", -:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:none`, `:off`" +:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`" ) diff --git a/src/args.jl b/src/args.jl index 83379dfd..3ea3efde 100644 --- a/src/args.jl +++ b/src/args.jl @@ -170,8 +170,8 @@ const _scaleAliases = Dict{Symbol,Symbol}( const _allGridSyms = [:x, :y, :z, :xy, :xz, :yx, :yz, :zx, :zy, :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, - :all, :both, :on, :yes, - :none, :off, :no] + :all, :both, :on, :yes, :show, + :none, :off, :no, :hide] const _allGridArgs = [_allGridSyms; string.(_allGridSyms); nothing] hasgrid(arg::Void, letter) = false hasgrid(arg::Bool, letter) = arg @@ -188,12 +188,12 @@ hasgrid(arg::AbstractString, letter) = hasgrid(Symbol(arg), letter) const _allShowaxisSyms = [:x, :y, :z, :xy, :xz, :yx, :yz, :zx, :zy, :xyz, :xzy, :yxz, :yzx, :zxy, :zyx, - :all, :both, :on, :yes, - :none, :off, :no] + :all, :both, :on, :yes, :show, + :off, :no, :hide] const _allShowaxisArgs = [_allGridSyms; string.(_allGridSyms)] showaxis(arg::Void, letter) = false showaxis(arg::Bool, letter) = arg -function hasgrid(arg::Symbol, letter) +function showaxis(arg::Symbol, letter) if arg in _allGridSyms arg in (:all, :both, :on, :yes) || contains(string(arg), string(letter)) else @@ -340,7 +340,8 @@ const _axis_defaults = KW( :gridalpha => 0.1, :gridstyle => :solid, :gridlinewidth => 0.5, - :tick_direction => :in, + :tick_direction => :in, + :showaxis => true, ) const _suppress_warnings = Set{Symbol}([ @@ -728,7 +729,7 @@ function processGridArg!(d::KW, arg, letter) d[Symbol(letter, :gridlinewidth)] = arg # color -elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid)) + elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_grid)) warn("Skipped grid arg $arg.") end @@ -753,13 +754,13 @@ function preprocessArgs!(d::KW) replaceAliases!(d, _keyAliases) # clear all axis stuff - if haskey(d, :axis) && d[:axis] in (:none, nothing, false) - d[:ticks] = nothing - d[:foreground_color_border] = RGBA(0,0,0,0) - d[:foreground_color_axis] = RGBA(0,0,0,0) - d[:grid] = false - delete!(d, :axis) - end + # if haskey(d, :axis) && d[:axis] in (:none, nothing, false) + # d[:ticks] = nothing + # d[:foreground_color_border] = RGBA(0,0,0,0) + # d[:foreground_color_axis] = RGBA(0,0,0,0) + # d[:grid] = false + # delete!(d, :axis) + # end # for letter in (:x, :y, :z) # asym = Symbol(letter, :axis) # if haskey(d, asym) || d[asym] in (:none, nothing, false) @@ -768,6 +769,13 @@ function preprocessArgs!(d::KW) # end # end + # handle axis args common to all axis + args = pop!(d, :axis, ()) + for arg in wraptuple(args) + for letter in (:x, :y, :z) + process_axis_arg!(d, arg, letter) + end + end # handle axis args for letter in (:x, :y, :z) asym = Symbol(letter, :axis) diff --git a/src/axes.jl b/src/axes.jl index 6d06a261..bf7175ed 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -70,7 +70,7 @@ function process_axis_arg!(d::KW, arg, letter = "") elseif arg == nothing d[Symbol(letter,:ticks)] = [] - elseif arg in _allShowaxisArgs + elseif T <: Bool || arg in _allShowaxisArgs d[Symbol(letter,:showaxis)] = showaxis(arg, letter) elseif typeof(arg) <: Number @@ -79,7 +79,7 @@ function process_axis_arg!(d::KW, arg, letter = "") elseif typeof(arg) <: Function d[Symbol(letter,:formatter)] = arg - else + elseif !handleColors!(d, arg, Symbol(letter, :foreground_color_axis)) warn("Skipped $(letter)axis arg $arg") end From 6d53594850bfc6ea94e1bd54e8edadf57dc83ef8 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 29 Sep 2017 15:09:28 +0200 Subject: [PATCH 373/720] implement showaxis for plotly --- src/backends/plotly.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1dd9060a..b3c40158 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -234,10 +234,11 @@ function plotly_axis(axis::Axis, sp::Subplot) :gridwidth => axis[:gridlinewidth], :zeroline => framestyle == :zerolines, :zerolinecolor => rgba_string(axis[:foreground_color_axis]), - :showline => framestyle in (:box, :axes), + :showline => framestyle in (:box, :axes) && axis[:showaxis], :linecolor => rgba_string(plot_color(axis[:foreground_color_axis])), :ticks => axis[:tick_direction] == :out ? "outside" : "inside", :mirror => framestyle == :box, + :showticklabels => axis[:showaxis], ) if letter in (:x,:y) @@ -251,7 +252,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) - ax[:tickcolor] = framestyle in (:zerolines, :grid) ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) + ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) # lims From 148ad8032f57f62b1b6f6bd2f63ae4a3bf806f0b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 29 Sep 2017 20:16:27 +0200 Subject: [PATCH 374/720] implement showaxis for pyplot --- src/backends/pyplot.jl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ea0ba6c7..d2146d68 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1077,6 +1077,24 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) py_set_axis_colors(sp, ax, axis) end + # showaxis + if !sp[:xaxis][:showaxis] + kw = KW() + for dir in (:top, :bottom) + ax[:spines][string(dir)][:set_visible](false) + kw[dir] = kw[Symbol(:label,dir)] = "off" + end + ax[:xaxis][:set_tick_params](; which="both", kw...) + end + if !sp[:yaxis][:showaxis] + kw = KW() + for dir in (:left, :right) + ax[:spines][string(dir)][:set_visible](false) + kw[dir] = kw[Symbol(:label,dir)] = "off" + end + ax[:yaxis][:set_tick_params](; which="both", kw...) + end + # aspect ratio aratio = sp[:aspect_ratio] if aratio != :none From 6e1cc8449b41b50e4b1d691379305508b9daf727 Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Sat, 23 Sep 2017 23:49:09 +0200 Subject: [PATCH 375/720] replace d by plotattributes inside recipes --- src/recipes.jl | 76 +++++++++++++++++++++++++------------------------- src/series.jl | 56 ++++++++++++++++++------------------- 2 files changed, 66 insertions(+), 66 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 876b3897..804a7074 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -79,7 +79,7 @@ function hvline_limits(axis::Axis) end @recipe function f(::Type{Val{:hline}}, x, y, z) - xmin, xmax = hvline_limits(d[:subplot][:xaxis]) + xmin, xmax = hvline_limits(plotattributes[:subplot][:xaxis]) n = length(y) newx = repmat(Float64[xmin, xmax, NaN], n) newy = vec(Float64[yi for i=1:3,yi=y]) @@ -91,7 +91,7 @@ end @deps hline path @recipe function f(::Type{Val{:vline}}, x, y, z) - ymin, ymax = hvline_limits(d[:subplot][:yaxis]) + ymin, ymax = hvline_limits(plotattributes[:subplot][:yaxis]) n = length(y) newx = vec(Float64[yi for i=1:3,yi=y]) newy = repmat(Float64[ymin, ymax, NaN], n) @@ -123,11 +123,11 @@ end # create a path from steps @recipe function f(::Type{Val{:steppre}}, x, y, z) - d[:x], d[:y] = make_steps(x, y, :steppre) + plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppre) seriestype := :path # create a secondary series for the markers - if d[:markershape] != :none + if plotattributes[:markershape] != :none @series begin seriestype := :scatter x := x @@ -144,11 +144,11 @@ end # create a path from steps @recipe function f(::Type{Val{:steppost}}, x, y, z) - d[:x], d[:y] = make_steps(x, y, :steppost) + plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppost) seriestype := :path # create a secondary series for the markers - if d[:markershape] != :none + if plotattributes[:markershape] != :none @series begin seriestype := :scatter x := x @@ -170,9 +170,9 @@ end # create vertical line segments from fill @recipe function f(::Type{Val{:sticks}}, x, y, z) n = length(x) - fr = d[:fillrange] + fr = plotattributes[:fillrange] if fr == nothing - yaxis = d[:subplot][:yaxis] + yaxis = plotattributes[:subplot][:yaxis] fr = if yaxis[:scale] == :identity 0.0 else @@ -191,7 +191,7 @@ end seriestype := :path # create a secondary series for the markers - if d[:markershape] != :none + if plotattributes[:markershape] != :none @series begin seriestype := :scatter x := x @@ -224,7 +224,7 @@ end @recipe function f(::Type{Val{:curves}}, x, y, z; npoints = 30) args = z != nothing ? (x,y,z) : (x,y) newx, newy = zeros(0), zeros(0) - fr = d[:fillrange] + fr = plotattributes[:fillrange] newfr = fr != nothing ? zeros(0) : nothing newz = z != nothing ? zeros(0) : nothing # lz = d[:line_z] @@ -274,9 +274,9 @@ end # create a bar plot as a filled step function @recipe function f(::Type{Val{:bar}}, x, y, z) - procx, procy, xscale, yscale, baseline = _preprocess_barlike(d, x, y) + procx, procy, xscale, yscale, baseline = _preprocess_barlike(plotattributes, x, y) nx, ny = length(procx), length(procy) - axis = d[:subplot][isvertical(d) ? :xaxis : :yaxis] + axis = plotattributes[:subplot][isvertical(plotattributes) ? :xaxis : :yaxis] cv = [discrete_value!(axis, xi)[1] for xi=procx] procx = if nx == ny cv @@ -287,7 +287,7 @@ end end # compute half-width of bars - bw = d[:bar_width] + bw = plotattributes[:bar_width] hw = if bw == nothing 0.5*_bar_width*ignorenan_mean(diff(procx)) else @@ -295,7 +295,7 @@ end end # make fillto a vector... default fills to 0 - fillto = d[:fillrange] + fillto = plotattributes[:fillrange] if fillto == nothing fillto = 0 end @@ -320,7 +320,7 @@ end expand_extrema!(axis, widen(ignorenan_extrema(xseg.pts)...)) # switch back - if !isvertical(d) + if !isvertical(plotattributes) xseg, yseg = yseg, xseg end @@ -389,8 +389,8 @@ end @recipe function f(::Type{Val{:barbins}}, x, y, z) - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) - if (d[:bar_width] == nothing) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y) + if (plotattributes[:bar_width] == nothing) bar_width := diff(edge) end x := _bin_centers(edge) @@ -402,7 +402,7 @@ end @recipe function f(::Type{Val{:scatterbins}}, x, y, z) - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y) xerror := diff(edge)/2 x := _bin_centers(edge) y := weights @@ -465,17 +465,17 @@ end @recipe function f(::Type{Val{:stepbins}}, x, y, z) - axis = d[:subplot][Plots.isvertical(d) ? :xaxis : :yaxis] + axis = plotattributes[:subplot][Plots.isvertical(plotattributes) ? :xaxis : :yaxis] - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, x, y) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, x, y) xpts, ypts = _stepbins_path(edge, weights, baseline, xscale, yscale) - if !isvertical(d) + if !isvertical(plotattributes) xpts, ypts = ypts, xpts end # create a secondary series for the markers - if d[:markershape] != :none + if plotattributes[:markershape] != :none @series begin seriestype := :scatter x := _bin_centers(edge) @@ -563,7 +563,7 @@ end @deps histogram barhist @recipe function f(::Type{Val{:barhist}}, x, y, z) - h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights]) x := h.edges[1] y := h.weights seriestype := :barbins @@ -572,7 +572,7 @@ end @deps barhist barbins @recipe function f(::Type{Val{:stephist}}, x, y, z) - h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights]) x := h.edges[1] y := h.weights seriestype := :stepbins @@ -581,7 +581,7 @@ end @deps stephist stepbins @recipe function f(::Type{Val{:scatterhist}}, x, y, z) - h = _make_hist((y,), d[:bins], normed = d[:normalize], weights = d[:weights]) + h = _make_hist((y,), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights]) x := h.edges[1] y := h.weights seriestype := :scatterbins @@ -597,11 +597,11 @@ end :bar => :barbins, :scatter => :scatterbins, :step => :stepbins, :steppost => :stepbins # :step can be mapped to :steppost in pre-processing ) - seriestype := get(st_map, d[:seriestype], d[:seriestype]) + seriestype := get(st_map, plotattributes[:seriestype], plotattributes[:seriestype]) - if d[:seriestype] == :scatterbins + if plotattributes[:seriestype] == :scatterbins # Workaround, error bars currently not set correctly by scatterbins - edge, weights, xscale, yscale, baseline = _preprocess_binlike(d, h.edges[1], h.weights) + edge, weights, xscale, yscale, baseline = _preprocess_binlike(plotattributes, h.edges[1], h.weights) xerror --> diff(h.edges[1])/2 seriestype := :scatter (Plots._bin_centers(edge), weights) @@ -648,7 +648,7 @@ Plots.@deps bins2d heatmap @recipe function f(::Type{Val{:histogram2d}}, x, y, z) - h = _make_hist((x, y), d[:bins], normed = d[:normalize], weights = d[:weights]) + h = _make_hist((x, y), plotattributes[:bins], normed = plotattributes[:normalize], weights = plotattributes[:weights]) x := h.edges[1] y := h.edges[2] z := Surface(h.weights) @@ -669,7 +669,7 @@ end @recipe function f(::Type{Val{:scatter3d}}, x, y, z) seriestype := :path3d - if d[:markershape] == :none + if plotattributes[:markershape] == :none markershape := :circle end linewidth := 0 @@ -732,17 +732,17 @@ end # we will create a series of path segments, where each point represents one # side of an errorbar @recipe function f(::Type{Val{:yerror}}, x, y, z) - error_style!(d) + error_style!(plotattributes) markershape := :hline - d[:x], d[:y] = error_coords(d[:x], d[:y], error_zipit(d[:yerror])) + plotattributes[:x], plotattributes[:y] = error_coords(plotattributes[:x], plotattributes[:y], error_zipit(plotattributes[:yerror])) () end @deps yerror path @recipe function f(::Type{Val{:xerror}}, x, y, z) - error_style!(d) + error_style!(plotattributes) markershape := :vline - d[:y], d[:x] = error_coords(d[:y], d[:x], error_zipit(d[:xerror])) + plotattributes[:y], plotattributes[:x] = error_coords(plotattributes[:y], plotattributes[:x], error_zipit(plotattributes[:xerror])) () end @deps xerror path @@ -841,9 +841,9 @@ end # function apply_series_recipe(d::KW, ::Type{Val{:quiver}}) @recipe function f(::Type{Val{:quiver}}, x, y, z) if :arrow in supported_attrs() - quiver_using_arrows(d) + quiver_using_arrows(plotattributes) else - quiver_using_hack(d) + quiver_using_hack(plotattributes) end () end @@ -948,10 +948,10 @@ end rs, cs, zs = findnz(z.surf) xlim := ignorenan_extrema(cs) ylim := ignorenan_extrema(rs) - if d[:markershape] == :none + if plotattributes[:markershape] == :none markershape := :circle end - if d[:markersize] == default(:markersize) + if plotattributes[:markersize] == default(:markersize) markersize := 1 end markerstrokewidth := 0 diff --git a/src/series.jl b/src/series.jl index 66518b78..52b672a1 100644 --- a/src/series.jl +++ b/src/series.jl @@ -128,15 +128,15 @@ immutable SliceIt end z = z.data end - xs, _ = convertToAnyVector(x, d) - ys, _ = convertToAnyVector(y, d) - zs, _ = convertToAnyVector(z, d) + xs, _ = convertToAnyVector(x, plotattributes) + ys, _ = convertToAnyVector(y, plotattributes) + zs, _ = convertToAnyVector(z, plotattributes) - fr = pop!(d, :fillrange, nothing) + fr = pop!(plotattributes, :fillrange, nothing) fillranges, _ = if typeof(fr) <: Number ([fr],nothing) else - convertToAnyVector(fr, d) + convertToAnyVector(fr, plotattributes) end mf = length(fillranges) @@ -148,7 +148,7 @@ immutable SliceIt end if mx > 0 && my > 0 && mz > 0 for i in 1:max(mx, my, mz) # add a new series - di = copy(d) + di = copy(plotattributes) xi, yi, zi = xs[mod1(i,mx)], ys[mod1(i,my)], zs[mod1(i,mz)] di[:x], di[:y], di[:z] = compute_xyz(xi, yi, zi) @@ -206,11 +206,11 @@ _apply_type_recipe{T<:Union{Integer,AbstractFloat}}(d, v::AbstractArray{T}) = v # handle "type recipes" by converting inputs, and then either re-calling or slicing @recipe function f(x, y, z) did_replace = false - newx = _apply_type_recipe(d, x) + newx = _apply_type_recipe(plotattributes, x) x === newx || (did_replace = true) - newy = _apply_type_recipe(d, y) + newy = _apply_type_recipe(plotattributes, y) y === newy || (did_replace = true) - newz = _apply_type_recipe(d, z) + newz = _apply_type_recipe(plotattributes, z) z === newz || (did_replace = true) if did_replace newx, newy, newz @@ -220,9 +220,9 @@ _apply_type_recipe{T<:Union{Integer,AbstractFloat}}(d, v::AbstractArray{T}) = v end @recipe function f(x, y) did_replace = false - newx = _apply_type_recipe(d, x) + newx = _apply_type_recipe(plotattributes, x) x === newx || (did_replace = true) - newy = _apply_type_recipe(d, y) + newy = _apply_type_recipe(plotattributes, y) y === newy || (did_replace = true) if did_replace newx, newy @@ -231,7 +231,7 @@ end end end @recipe function f(y) - newy = _apply_type_recipe(d, y) + newy = _apply_type_recipe(plotattributes, y) if y !== newy newy else @@ -244,7 +244,7 @@ end @recipe function f(v1, v2, v3, v4, vrest...) did_replace = false newargs = map(v -> begin - newv = _apply_type_recipe(d, v) + newv = _apply_type_recipe(plotattributes, v) if newv !== v did_replace = true end @@ -271,13 +271,13 @@ function wrap_surfaces(d::KW) end end -@recipe f(n::Integer) = is3d(get(d,:seriestype,:path)) ? (SliceIt, n, n, n) : (SliceIt, n, n, nothing) +@recipe f(n::Integer) = is3d(get(plotattributes,: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) + if all3D(plotattributes) n,m = size(mat) - wrap_surfaces(d) + wrap_surfaces(plotattributes) SliceIt, 1:m, 1:n, Surface(mat) else SliceIt, nothing, mat, nothing @@ -286,10 +286,10 @@ end # if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface @recipe function f{T<:AbstractMatrix}(fmt::Formatted{T}) - if all3D(d) + if all3D(plotattributes) mat = fmt.data n,m = size(mat) - wrap_surfaces(d) + wrap_surfaces(plotattributes) SliceIt, 1:m, 1:n, Formatted(Surface(mat), fmt.formatter) else SliceIt, nothing, fmt, nothing @@ -329,7 +329,7 @@ end else seriestype := :heatmap yflip --> true - z, d[:fillcolor] = replace_image_with_heatmap(mat) + z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat) SliceIt, 1:m, 1:n, Surface(z) end end @@ -359,7 +359,7 @@ end # function without range... use the current range of the x-axis @recipe function f{F<:Function}(f::FuncOrFuncs{F}) - plt = d[:plot_object] + plt = plotattributes[:plot_object] xmin, xmax = try axis_limits(plt[1][:xaxis]) catch @@ -421,7 +421,7 @@ end # seriestype := :path3d # end # end - wrap_surfaces(d) + wrap_surfaces(plotattributes) SliceIt, x, y, z end @@ -431,7 +431,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) + wrap_surfaces(plotattributes) SliceIt, x, y, Surface(zf, x, y) # TODO: replace with SurfaceFunction when supported end @@ -439,10 +439,10 @@ end # # surface-like... matrix grid @recipe function f(x::AVec, y::AVec, z::AMat) - if !like_surface(get(d, :seriestype, :none)) - d[:seriestype] = :contour + if !like_surface(get(plotattributes, :seriestype, :none)) + plotattributes[:seriestype] = :contour end - wrap_surfaces(d) + wrap_surfaces(plotattributes) SliceIt, x, y, Surface(z) end @@ -494,7 +494,7 @@ end @recipe f{R1<:Number,R2<:Number,R3<:Number}(xyz::Tuple{R1,R2,R3}) = [xyz[1]], [xyz[2]], [xyz[3]] # these might be points+velocity, or OHLC or something else -@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::AVec{Tuple{R1,R2,R3,R4}}) = get(d,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) +@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::AVec{Tuple{R1,R2,R3,R4}}) = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) @recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::Tuple{R1,R2,R3,R4}) = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]] @@ -556,7 +556,7 @@ group_as_matrix(t) = false @series begin label --> string(glab) idxfilter --> groupby.groupIds[i] - for (key,val) in d + for (key,val) in plotattributes if splittable_kw(key, val, lengthGroup) :($key) := split_kw(key, val, groupby.groupIds[i]) end @@ -578,7 +578,7 @@ group_as_matrix(t) = false end x_u = unique(x) x_ind = Dict(zip(x_u, 1:length(x_u))) - for (key,val) in d + for (key,val) in plotattributes if splittable_kw(key, val, lengthGroup) :($key) := groupedvec2mat(x_ind, x, val, groupby) end From 489e48411754620f2aa19cd236950f88956ce20e Mon Sep 17 00:00:00 2001 From: Jan Weidner Date: Fri, 29 Sep 2017 23:24:58 +0200 Subject: [PATCH 376/720] bump required RecipesBase to 0.2.3 --- REQUIRE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/REQUIRE b/REQUIRE index 888aaf7d..a99ac547 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,6 +1,6 @@ julia 0.6 -RecipesBase 0.2.0 +RecipesBase 0.2.3 PlotUtils 0.4.1 PlotThemes 0.1.3 Reexport From bf4dd78a7dd9e35f32241a7d962c97f3fde2fc74 Mon Sep 17 00:00:00 2001 From: apalugniok Date: Sun, 1 Oct 2017 10:29:44 +0100 Subject: [PATCH 377/720] Change GR default 3D view angles to match PyPlot --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index fcd93547..d236db15 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -750,7 +750,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end - GR.setspace(zmin, zmax, 40, 70) + GR.setspace(zmin, zmax, 35, 60) xtick = GR.tick(xmin, xmax) / 2 ytick = GR.tick(ymin, ymax) / 2 ztick = GR.tick(zmin, zmax) / 2 From 93df7f43679be2ce131129846ceec4f5461e9c46 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 1 Oct 2017 19:09:24 +0200 Subject: [PATCH 378/720] implement showaxis for glvisualize --- src/backends/glvisualize.jl | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 1bdb79df..bbd5605a 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -732,15 +732,25 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are xlim = Plots.axis_limits(xaxis) ylim = Plots.axis_limits(yaxis) - if !(xaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none) + if !(xaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none) && xaxis[:showaxis] ticklabels = map(model) do m mirror = xaxis[:mirror] t, positions, offsets = draw_ticks(xaxis, xticks, true, sp[:framestyle] == :origin, ylim, m) - mirror = xaxis[:mirror] - t, positions, offsets = draw_ticks( - yaxis, yticks, false, sp[:framestyle] == :origin, xlim, m, - t, positions, offsets - ) + end + kw_args = Dict{Symbol, Any}( + :position => map(x-> x[2], ticklabels), + :offset => map(last, ticklabels), + :color => fcolor, + :relative_scale => pointsize(xaxis[:tickfont]), + :scale_primitive => false + ) + push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) + end + + if !(yaxis[:ticks] in (nothing, false, :none)) && !(sp[:framestyle] == :none) && yaxis[:showaxis] + ticklabels = map(model) do m + mirror = yaxis[:mirror] + t, positions, offsets = draw_ticks(yaxis, yticks, false, sp[:framestyle] == :origin, xlim, m) end kw_args = Dict{Symbol, Any}( :position => map(x-> x[2], ticklabels), From ff751ca423803d43a6fb2ca16e59268caaf7fa7a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 1 Oct 2017 20:29:46 +0200 Subject: [PATCH 379/720] implement showaxis and basic framestyles for pgfplots --- src/backends/pgfplots.jl | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 97d68421..153ee808 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -32,6 +32,7 @@ const _pgfplots_attr = merge_with_base_supported([ :aspect_ratio, # :match_dimensions, :tick_direction, + :framestyle, ]) const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] @@ -107,6 +108,18 @@ const _pgf_annotation_halign = KW( :right => "left" ) +const _pgf_framestyles = [:box, :axes, :grid, :none] +const _pgf_framestyle_defaults = Dict(:semi => :box, :origin => :axes, :zerolines => :axes) +function pgf_framestyle(style::Symbol) + if style in _pgf_framestyles + return style + else + default_style = get(_pgf_framestyle_defaults, style, :axes) + warn("Framestyle :$style is not (yet) supported by the PGFPlots backend. :$default_style was cosen instead.") + default_style + end +end + # -------------------------------------------------------------------------------------- # takes in color,alpha, and returns color and alpha appropriate for pgf style @@ -246,6 +259,9 @@ function pgf_axis(sp::Subplot, letter) style = [] kw = KW() + # set to supported framestyle + framestyle = pgf_framestyle(sp[:framestyle]) + # axis guide kw[Symbol(letter,:label)] = axis[:guide] @@ -263,12 +279,12 @@ function pgf_axis(sp::Subplot, letter) end # ticks on or off - if axis[:ticks] in (nothing, false) + if axis[:ticks] in (nothing, false) || framestyle == :none push!(style, "$(letter)majorticks=false") end # grid on or off - if axis[:grid] + if axis[:grid] && framestyle != :none push!(style, "$(letter)majorgrids = true") end @@ -280,13 +296,29 @@ function pgf_axis(sp::Subplot, letter) kw[Symbol(letter,:max)] = lims[2] end - if !(axis[:ticks] in (nothing, false, :none)) + if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none ticks = get_ticks(axis) push!(style, string(letter, "tick = {", join(ticks[1],","), "}")) - push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) + if axis[:showaxis] + push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) + else + push!(style, string(letter, "ticklabels = {}")) + end push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside"))) end + # framestyle + if sp[:framestyle] == :axes + push!(style, "axis lines = left") + end + + if !axis[:showaxis] + push!(style, "separate axis lines") + end + if !axis[:showaxis] || framestyle in (:grid, :none) + push!(style, string(letter, " axis line style = {draw opacity = 0}")) + end + # return the style list and KW args style, kw end From 33e5a51a28a998683440826eb920fbe664ee1307 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 22 May 2017 14:33:32 +0200 Subject: [PATCH 380/720] add submodule Measure --- src/Plots.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Plots.jl b/src/Plots.jl index c75a8e65..eaba8acb 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -133,11 +133,15 @@ ignorenan_extrema(x) = Base.extrema(x) # --------------------------------------------------------- +module Measure import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox export BBox, BoundingBox, mm, cm, inch, pt, px, pct, w, h +end +importall Measure +export BBox, BoundingBox # --------------------------------------------------------- include("types.jl") From b717cf1dc0cf0832473e332e414b965192d1067e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 2 Oct 2017 08:24:59 +0200 Subject: [PATCH 381/720] Rename submodule to PlotMeasures --- src/Plots.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index eaba8acb..d3966d09 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -133,14 +133,15 @@ ignorenan_extrema(x) = Base.extrema(x) # --------------------------------------------------------- -module Measure +module PlotMeasures import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox export BBox, BoundingBox, mm, cm, inch, pt, px, pct, w, h end -importall Measure + +importall .PlotMeasures export BBox, BoundingBox # --------------------------------------------------------- From 4f6a920f72fb8bbf3f9124f4e994daa2286f4a17 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 2 Oct 2017 08:28:25 +0200 Subject: [PATCH 382/720] Import Measures into Plots --- src/Plots.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index d3966d09..24a9989c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -138,10 +138,10 @@ import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox export BBox, BoundingBox, mm, cm, inch, pt, px, pct, w, h - end -importall .PlotMeasures +using .PlotMeasures +import .PlotMeasures: Length, AbsoluteLength, Measure, width, height export BBox, BoundingBox # --------------------------------------------------------- From cd958a6c6885706b4d49236813a3b8af36bf4ce9 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 2 Oct 2017 08:53:41 +0200 Subject: [PATCH 383/720] Fix barwidth to minimum(diff) not mean(diff) --- src/axes.jl | 2 +- src/recipes.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index f989a8fb..303e24db 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -365,7 +365,7 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = _bar_width * ignorenan_mean(diff(data)) + bw = d[:bar_width] = _bar_width * ignorenan_minimum(filter(x->x>0,diff(data))) end axis = sp.attr[Symbol(dsym, :axis)] expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw)) diff --git a/src/recipes.jl b/src/recipes.jl index 876b3897..5f844967 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -289,7 +289,7 @@ end # compute half-width of bars bw = d[:bar_width] hw = if bw == nothing - 0.5*_bar_width*ignorenan_mean(diff(procx)) + 0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx))) else Float64[0.5_cycle(bw,i) for i=1:length(procx)] end From f3566a493362c88239b3ece5b2db601a947066d5 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 2 Oct 2017 10:02:39 +0200 Subject: [PATCH 384/720] sort before taking diff --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 303e24db..debb3773 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -365,7 +365,7 @@ function expand_extrema!(sp::Subplot, d::KW) bw = d[:bar_width] if bw == nothing - bw = d[:bar_width] = _bar_width * ignorenan_minimum(filter(x->x>0,diff(data))) + bw = d[:bar_width] = _bar_width * ignorenan_minimum(filter(x->x>0,diff(sort(data)))) end axis = sp.attr[Symbol(dsym, :axis)] expand_extrema!(axis, ignorenan_maximum(data) + 0.5maximum(bw)) From 2a1140c0b3e56aa360ea60662306dbbc8afbdee3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 2 Oct 2017 15:07:16 +0200 Subject: [PATCH 385/720] include PlotMeasures in example 29 --- src/examples.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/examples.jl b/src/examples.jl index 4393ab60..fabb368d 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -288,6 +288,7 @@ PlotExample("Heatmap, categorical axes, and aspect_ratio", PlotExample("Layouts, margins, label rotation, title location", "", [:(begin + using Plots.PlotMeasures # for Measures, e.g. mm and px plot(rand(100,6),layout=@layout([a b; c]),title=["A" "B" "C"], title_location=:left, left_margin=[20mm 0mm], bottom_margin=10px, xrotation=60) From ff0f1c5c500a585d2cbe1c6fe445222ded4ea703 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 3 Oct 2017 10:28:54 +0200 Subject: [PATCH 386/720] update news.md --- NEWS.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 603ed9da..491b699f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ #### notes on release changes, ongoing development, and future planned work -- All new development should target 0.12! +- All new development should target 0.13! - Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - `backports` branch is for Julia 0.5 @@ -11,6 +11,29 @@ --- ## (current master) +## 0.13.0 + +- support `plotattributes` rather than `d` in recipes +- no longer export `w`, `h` and names from Measures.jl; use `using Plots.PlotMeasures` to get these names back +- `bar_width` now depends on the minimum distance between bars, not the mean +- better automatic x axis limits for plotting Functions +- `tick_direction` attribute now allows ticks to be on the inside of the plot border +- removed a bug where `p1 = plot(randn(10)); plot(p1, p2)` made `display(p1)` impossible +- allow `plot([])` to generate an empty plot +- add `origin` framestyle +- ensure finite bin number on histograms with only one unique value +- better automatic histogram bins for 2d histograms +- more informative error message on passing unsupported seriestype in a recipe +- allow grouping in user recipes +- GR now has `line_z` and `fill_z` attributes for determining the color of shapes and lines +- change GR default view angle for 3D plots to match that of PyPlot +- fix `clims` on GR +- fix `marker_z` for plotly backend +- implement `framestyle` for plotly +- fix logscale bug error for values < 1e-16 on pyplot +- fix an issue on pyplot where >1 colorbar would be shown if there was >1 series +- fix `writemime` for eps + ## 0.12.4 - added a new `framestyle` argument with choices: :box, :semi, :axes, :grid and :none From efd116ec52633e9461fb7e93a4b92f2c6bf9e9c4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 3 Oct 2017 10:29:06 +0200 Subject: [PATCH 387/720] deactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 24a9989c..7bb386c5 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 54838d386dd3fff2213589884c910c097c0d236b Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 3 Oct 2017 10:31:05 +0200 Subject: [PATCH 388/720] Reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 7bb386c5..24a9989c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 53a4c36aab83ebd00a43ab6efc501d0d7d2e98bf Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 3 Oct 2017 15:12:01 +0200 Subject: [PATCH 389/720] Make Measures available in Plots in general too --- src/Plots.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 24a9989c..560588db 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots @@ -133,6 +133,7 @@ ignorenan_extrema(x) = Base.extrema(x) # --------------------------------------------------------- +import Measures module PlotMeasures import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h From 073724a84c47cf4de5b2c0fe755389c8df66eec8 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Tue, 3 Oct 2017 15:14:10 +0200 Subject: [PATCH 390/720] reactivate --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 560588db..e730e65c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 3d86d5f530612092a70236abb258eb9254650a6a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 4 Oct 2017 11:38:32 +0200 Subject: [PATCH 391/720] Apply automatic limits for vectors of functions --- src/series.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index 52b672a1..7e7729ea 100644 --- a/src/series.jl +++ b/src/series.jl @@ -371,6 +371,13 @@ end end # try some intervals over which the function may be defined +function tryrange(F::T, vec) where T <: AbstractArray + rets = [tryrange(f, vec) for f in F] # get the preferred for each + inds = indexin(rets, vec) # get the last attempt (most likely to fit all) + rets .= [tryrange(f, vec[maximum(inds):maximum(inds)]) for f in F] # ensure that all functions compute there + rets[1] +end + function tryrange(F, vec) for v in vec try @@ -379,7 +386,7 @@ function tryrange(F, vec) catch end end - error("Function not defined over the given interval, $vec") + error("$F is not a Function, or is not defined at any of the values $vec") end # # # -------------------------------------------------------------------- From 0327c9101e63848338c73c318b66bf26885c6e11 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 4 Oct 2017 11:44:20 +0200 Subject: [PATCH 392/720] slight refactor for clarity --- src/series.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index 7e7729ea..84f3cc21 100644 --- a/src/series.jl +++ b/src/series.jl @@ -373,8 +373,8 @@ end # try some intervals over which the function may be defined function tryrange(F::T, vec) where T <: AbstractArray rets = [tryrange(f, vec) for f in F] # get the preferred for each - inds = indexin(rets, vec) # get the last attempt (most likely to fit all) - rets .= [tryrange(f, vec[maximum(inds):maximum(inds)]) for f in F] # ensure that all functions compute there + maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) + rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there rets[1] end From 5567038cec70f6eae82f2b9ef8bb450b7e3d5749 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 4 Oct 2017 11:47:20 +0200 Subject: [PATCH 393/720] simplify --- src/series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index 84f3cc21..c0d7d4c2 100644 --- a/src/series.jl +++ b/src/series.jl @@ -371,7 +371,7 @@ end end # try some intervals over which the function may be defined -function tryrange(F::T, vec) where T <: AbstractArray +function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there From e3b0f7cd94c89bfc75a7c1dfff993eb92c1a1ece Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 4 Oct 2017 13:40:56 +0200 Subject: [PATCH 394/720] pgfplots: remove axis arrows and implement origin and zerolines framestyles --- src/backends/pgfplots.jl | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 153ee808..b54d8aa0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -108,8 +108,8 @@ const _pgf_annotation_halign = KW( :right => "left" ) -const _pgf_framestyles = [:box, :axes, :grid, :none] -const _pgf_framestyle_defaults = Dict(:semi => :box, :origin => :axes, :zerolines => :axes) +const _pgf_framestyles = [:box, :axes, :origin, :zerolines, :grid, :none] +const _pgf_framestyle_defaults = Dict(:semi => :box) function pgf_framestyle(style::Symbol) if style in _pgf_framestyles return style @@ -308,14 +308,22 @@ function pgf_axis(sp::Subplot, letter) end # framestyle - if sp[:framestyle] == :axes - push!(style, "axis lines = left") + if framestyle in (:axes, :origin) + axispos = framestyle == :axes ? "left" : "middle" + # the * after lines disables the arrows at the axes + push!(style, string("axis lines* = ", axispos)) + end + + if framestyle == :zerolines + push!(style, string("extra ", letter, " ticks = 0")) + push!(style, string("extra ", letter, " tick labels = ")) + push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {color = black, draw opacity=1.0, line width=0.5), solid}}")) end if !axis[:showaxis] push!(style, "separate axis lines") end - if !axis[:showaxis] || framestyle in (:grid, :none) + if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none) push!(style, string(letter, " axis line style = {draw opacity = 0}")) end From f5ee5ea8148f92ebc8242a41b7e920f7e2933ee2 Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Wed, 4 Oct 2017 14:26:35 -0700 Subject: [PATCH 395/720] Fix `line_z` for PyPlot backend `LineCollection` expects an array with pairs of coordinates, corresponding to the starting and ending points of each segment. --- src/backends/pyplot.jl | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ea0ba6c7..12442aec 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -508,11 +508,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = if is3d(st) for rng in iter_segments(x, y, z) length(rng) < 2 && continue - push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)) for i in rng]) + for i in rng[1:end-1] + push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)), + (_cycle(x,i+1),_cycle(y,i+1),_cycle(z,i+1))]) + end end - # for i=1:n - # segments[i] = [(_cycle(x,i), _cycle(y,i), _cycle(z,i)), (_cycle(x,i+1), _cycle(y,i+1), _cycle(z,i+1))] - # end + lc = pyart3d["Line3DCollection"](segments; kw...) lc[:set_array](lz) ax[:add_collection3d](lc, zs=z) #, zdir='y') @@ -520,11 +521,11 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) else for rng in iter_segments(x, y) length(rng) < 2 && continue - push!(segments, [(_cycle(x,i),_cycle(y,i)) for i in rng]) + for i in rng[1:end-1] + push!(segments, [(_cycle(x,i),_cycle(y,i)), (_cycle(x,i+1),_cycle(y,i+1))]) + end end - # for i=1:n - # segments[i] = [(_cycle(x,i), _cycle(y,i)), (_cycle(x,i+1), _cycle(y,i+1))] - # end + lc = pycollections["LineCollection"](segments; kw...) lc[:set_array](lz) ax[:add_collection](lc) From 514cd1bd3735c63d8642a044c2a3a048c492501b Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Wed, 4 Oct 2017 15:10:36 -0700 Subject: [PATCH 396/720] normalize colors even when plotting without colorbars --- src/backends/pyplot.jl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 12442aec..9918ec08 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -499,11 +499,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :zorder => plt.n, :cmap => py_linecolormap(series), :linewidth => py_dpi_scale(plt, series[:linewidth]), - :linestyle => py_linestyle(st, series[:linestyle]) + :linestyle => py_linestyle(st, series[:linestyle]), + :norm => pycolors["Normalize"](; extrakw...) ) - if needs_colorbar - kw[:norm] = pycolors["Normalize"](; extrakw...) - end lz = collect(series[:line_z]) handle = if is3d(st) for rng in iter_segments(x, y, z) From 878fa48afad20a00f7765dad1b691d20ae66627c Mon Sep 17 00:00:00 2001 From: JackDevine Date: Thu, 5 Oct 2017 21:35:38 +1300 Subject: [PATCH 397/720] PyPlot legends now show marker types. --- src/backends/pyplot.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index ea0ba6c7..26af0634 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1183,6 +1183,12 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) color = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, 4) ) + elseif series[:seriestype] == :path + PyPlot.plt[:Line2D]((0,1),(0,0), + color = py_color(_cycle(series[:fillcolor],1)), + linewidth = py_dpi_scale(plt, 1), + marker = py_marker(series[:markershape]) + ) else series[:serieshandle][1] end) From 520dc80eeb3301abeca26ae7b1200c50cb533fa9 Mon Sep 17 00:00:00 2001 From: JackDevine Date: Thu, 5 Oct 2017 22:58:18 +1300 Subject: [PATCH 398/720] Added marker strokes --- src/backends/pyplot.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 26af0634..4c9173c7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1187,7 +1187,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, 1), - marker = py_marker(series[:markershape]) + marker = py_marker(series[:markershape]), + markeredgecolor = py_markerstrokecolor(series), + markerfacecolor = py_markercolor(series) ) else series[:serieshandle][1] From b37f2141a1e7eb1bc74ff3d3403f13bd71bb3e20 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:08:15 +0200 Subject: [PATCH 399/720] Also import px and pct into PlotMeasures Necessary for example 29 to work --- src/Plots.jl | 7 +++++-- src/layouts.jl | 4 ---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index e730e65c..e2ffa95c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -138,12 +138,15 @@ module PlotMeasures import Measures import Measures: Length, AbsoluteLength, Measure, BoundingBox, mm, cm, inch, pt, width, height, w, h const BBox = Measures.Absolute2DBox -export BBox, BoundingBox, mm, cm, inch, pt, px, pct, w, h + +# allow pixels and percentages +const px = AbsoluteLength(0.254) +const pct = Length{:pct, Float64}(1.0) +export BBox, BoundingBox, mm, cm, inch, px, pct, pt, w, h end using .PlotMeasures import .PlotMeasures: Length, AbsoluteLength, Measure, width, height -export BBox, BoundingBox # --------------------------------------------------------- include("types.jl") diff --git a/src/layouts.jl b/src/layouts.jl index 9e90a2f1..9bd4d3b2 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -1,10 +1,6 @@ # NOTE: (0,0) is the top-left !!! -# allow pixels and percentages -const px = AbsoluteLength(0.254) -const pct = Length{:pct, Float64}(1.0) - to_pixels(m::AbsoluteLength) = m.value / 0.254 const _cbar_width = 5mm From fdf2d5b20b90a8d697e1c2e789e132f235ed824e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:22:12 +0200 Subject: [PATCH 400/720] ready for release --- NEWS.md | 5 +++++ src/Plots.jl | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 491b699f..6f68c1f5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,11 @@ --- ## (current master) +## 0.13.1 + +- fix a bug when passing a vector of functions with no bounds (e.g. `plot([sin, cos])`) +- export pct and px from Plots.PlotMeasures + ## 0.13.0 - support `plotattributes` rather than `d` in recipes diff --git a/src/Plots.jl b/src/Plots.jl index e2ffa95c..33703c9f 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 9fc0c98722af38909ffae8ceca600e0ee222eccd Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:25:04 +0200 Subject: [PATCH 401/720] precompile --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 33703c9f..e2ffa95c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 77fa5454e21ac47d93852d82e6896e2aa01f88a4 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:27:51 +0200 Subject: [PATCH 402/720] remember backticks --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 6f68c1f5..05f416f6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,7 +14,7 @@ ## 0.13.1 - fix a bug when passing a vector of functions with no bounds (e.g. `plot([sin, cos])`) -- export pct and px from Plots.PlotMeasures +- export `pct` and `px` from Plots.PlotMeasures ## 0.13.0 From 531a38bc39a7e64ee0d8f905e7d112ae23c6d4e9 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:28:52 +0200 Subject: [PATCH 403/720] no prec --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index e2ffa95c..33703c9f 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 78e3b69cc57b94b134b9980a2d40717e221a8683 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 12:30:29 +0200 Subject: [PATCH 404/720] prec --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 33703c9f..e2ffa95c 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 12488bf2b0cff37641055ee26a37607615ceb91e Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 5 Oct 2017 13:24:21 +0200 Subject: [PATCH 405/720] Drop tests for pyplot (temporarily) revisit 12 oct --- test/runtests.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/runtests.jl b/test/runtests.jl index 3f471735..4f0b2ad0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,12 +16,12 @@ img_eps = isinteractive() ? 1e-2 : 10e-2 end -@testset "PyPlot" begin - @test pyplot() == Plots.PyPlotBackend() - @test backend() == Plots.PyPlotBackend() - - image_comparison_facts(:pyplot, eps=img_eps) -end +#@testset "PyPlot" begin +# @test pyplot() == Plots.PyPlotBackend() +# @test backend() == Plots.PyPlotBackend() +# +# image_comparison_facts(:pyplot, eps=img_eps) +#end @testset "UnicodePlots" begin @test unicodeplots() == Plots.UnicodePlotsBackend() From 16d18552f85c2c45b71bd55f8524f4c05eed2bd4 Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Thu, 5 Oct 2017 20:49:17 -0700 Subject: [PATCH 406/720] Allow `line_z` to specify color across multiple lines --- 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 9918ec08..c42f6547 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -502,7 +502,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :linestyle => py_linestyle(st, series[:linestyle]), :norm => pycolors["Normalize"](; extrakw...) ) - lz = collect(series[:line_z]) + lz = _cycle(series[:line_z], 1:n) handle = if is3d(st) for rng in iter_segments(x, y, z) length(rng) < 2 && continue From 0c5a9172abf12c9d1c005e231de8540762bef263 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 6 Oct 2017 20:03:19 +0100 Subject: [PATCH 407/720] Added camera attribute processing. --- src/arg_desc.jl | 1 + src/args.jl | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index ce24b8e0..53c8b51f 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -94,6 +94,7 @@ const _arg_desc = KW( :subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.", :colorbar_title => "String. Title of colorbar.", :framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)", +:camera => "NTuple{2, Int(GR)/Real(Other)}. Sets the view angle (azimuthal, elevation) for 3D plots", # axis args :guide => "String. Axis guide (label).", diff --git a/src/args.jl b/src/args.jl index 3ea3efde..f36f2908 100644 --- a/src/args.jl +++ b/src/args.jl @@ -316,6 +316,7 @@ const _subplot_defaults = KW( :subplot_index => -1, :colorbar_title => "", :framestyle => :axes, + :camera => (30,30), ) const _axis_defaults = KW( @@ -532,6 +533,7 @@ add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, : add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor) +add_aliases(:camera, :cam) # add all pluralized forms to the _keyAliases dict for arg in keys(_series_defaults) From 65a28e76e548e16938b3eb9f2602afb6b21cef6d Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 6 Oct 2017 20:06:39 +0100 Subject: [PATCH 408/720] Implemented camera attribute for GR. --- src/backends/gr.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0d1d5a21..21d2c5db 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -34,6 +34,7 @@ const _gr_attr = merge_with_base_supported([ :arrow, :framestyle, :tick_direction, + :camera, ]) const _gr_seriestype = [ :path, :scatter, @@ -750,7 +751,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end - GR.setspace(zmin, zmax, 35, 60) + GR.setspace(zmin, zmax, sp[:camera]...) xtick = GR.tick(xmin, xmax) / 2 ytick = GR.tick(ymin, ymax) / 2 ztick = GR.tick(zmin, zmax) / 2 From 94e79f1e4cfef52da891e8bc3d592ac28b14ba6b Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 6 Oct 2017 20:07:31 +0100 Subject: [PATCH 409/720] Implemented camera attribute for PyPlot. --- src/backends/pyplot.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 6ad195a2..e3b70eb9 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -35,6 +35,7 @@ const _pyplot_attr = merge_with_base_supported([ :stride, :framestyle, :tick_direction, + :camera, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -1104,6 +1105,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) ax[:set_aspect](isa(aratio, Symbol) ? string(aratio) : aratio, anchor = "C") end + #camera/view angle + if is3d(sp) + #convert azimuthal to match GR behaviour + #view_init(elevation, azimuthal) so reverse :camera args + ax[:view_init]((sp[:camera].-(90,0))[end:-1:1]...) + end + # legend py_add_legend(plt, sp, ax) From 0fb1a0ed6bfc579f7577aae59de59819bac8e104 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 6 Oct 2017 20:07:48 +0100 Subject: [PATCH 410/720] Implemented camera attribute for PGFPlots. --- src/backends/pgfplots.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index b54d8aa0..a5f1a1b0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -33,6 +33,7 @@ const _pgfplots_attr = merge_with_base_supported([ # :match_dimensions, :tick_direction, :framestyle, + :camera, ]) const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] @@ -380,6 +381,11 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:legendPos] = _pgfplots_legend_pos[legpos] end + if is3d(sp) + azim, elev = sp[:camera] + kw[:view] = "{$(azim)}{$(elev)}" + end + axisf = PGFPlots.Axis if sp[:projection] == :polar axisf = PGFPlots.PolarAxis From ccb3cadd2a9e9fa7a9d372bbf21c79542bcc916c Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 6 Oct 2017 20:09:39 +0100 Subject: [PATCH 411/720] Implemented camera attribute for Plotly/PlotlyJS. --- src/backends/plotly.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b3c40158..c67511d2 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -35,6 +35,7 @@ const _plotly_attr = merge_with_base_supported([ :clims, :framestyle, :tick_direction, + :camera, ]) const _plotly_seriestype = [ @@ -324,10 +325,21 @@ function plotly_layout(plt::Plot) # if any(is3d, seriesargs) if is3d(sp) + azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour + theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis d_out[:scene] = KW( Symbol("xaxis$spidx") => plotly_axis(sp[:xaxis], sp), Symbol("yaxis$spidx") => plotly_axis(sp[:yaxis], sp), Symbol("zaxis$spidx") => plotly_axis(sp[:zaxis], sp), + + #2.6 multiplier set camera eye such that whole plot can be seen + :camera => KW( + :eye => KW( + :x => cosd(azim)*sind(theta)*2.6, + :y => sind(azim)*sind(theta)*2.6, + :z => cosd(theta)*2.6, + ), + ), ) else d_out[Symbol("xaxis$spidx")] = plotly_axis(sp[:xaxis], sp) From cb7498a30d023465969aff505899f55a67da9761 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 7 Oct 2017 21:02:14 +0200 Subject: [PATCH 412/720] fix linestyle on gr --- src/backends/gr.jl | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0d1d5a21..d78aa804 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -943,16 +943,22 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st in (:path, :scatter) if length(x) > 1 + lz = series[:line_z] + segments_iterator = if lz != nothing && length(lz) > 1 + [i:(i + 1) for i in 1:(length(x) - 1)] + else + iter_segments(x, y) + end # do area fill if frng != nothing GR.setfillintstyle(GR.INTSTYLE_SOLID) fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng)) - for i in 1:length(x) - 1 + for (i, rng) in enumerate(segments_iterator) gr_set_fillcolor(get_fillcolor(sp, series, i)) - xseg = _cycle(x, [i, i+1, i+1, i]) - yseg = [_cycle(fr_from, [i, i+1]); _cycle(fr_to, [i+1, i])] + fx = _cycle(x, vcat(rng, reverse(rng))) + fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) - GR.fillarea(xseg, yseg) + GR.fillarea(fx, fy) end gr_set_line(1, :solid, yaxis[:foreground_color_axis]) GR.settransparency(1) @@ -961,12 +967,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st == :path - for i in 1:length(x) - 1 - xseg = x[i:(i + 1)] - yseg = y[i:(i + 1)] + for (i, rng) in enumerate(segments_iterator) gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) - arrowside = (i == length(y) - 1) && isa(series[:arrow], Arrow) ? series[:arrow].side : :none - gr_polyline(xseg, yseg; arrowside = arrowside) + arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none + gr_polyline(x[rng], y[rng]; arrowside = arrowside) end gr_set_line(1, :solid, yaxis[:foreground_color_axis]) cmap && gr_colorbar(sp, clims) @@ -1036,15 +1040,20 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st in (:path3d, :scatter3d) # draw path if st == :path3d - for i in 1:length(x) - 1 - xseg = x[i:(i + 1)] - yseg = y[i:(i + 1)] - zseg = z[i:(i + 1)] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) - GR.polyline3d(xseg, yseg, zseg) + if length(x) > 1 + lz = series[:line_z] + segments_iterator = if lz != nothing && length(lz) > 1 + [i:(i + 1) for i in 1:(length(x) - 1)] + else + iter_segments(x, y, z) + end + for (i, rng) in enumerate(segments_iterator) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) + GR.polyline3d(x[rng], y[rng], z[rng]) + end + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + cmap && gr_colorbar(sp, clims) end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - cmap && gr_colorbar(sp, clims) end # draw markers From cf6f7035b6d9badc5e879ecf2c27d8a5dcd42d08 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 7 Oct 2017 20:05:05 +0100 Subject: [PATCH 413/720] Added extra :camera aliases. --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index f36f2908..505b1d74 100644 --- a/src/args.jl +++ b/src/args.jl @@ -533,7 +533,7 @@ add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, : add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor) -add_aliases(:camera, :cam) +add_aliases(:camera, :cam, :view, :viewangle, :view_angle) # add all pluralized forms to the _keyAliases dict for arg in keys(_series_defaults) From f4bc2e06490fadb5bc5957af3bc85bc05fdc87ff Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 7 Oct 2017 20:05:53 +0100 Subject: [PATCH 414/720] Convert :camera attribute input for GR. --- src/arg_desc.jl | 2 +- src/backends/gr.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 53c8b51f..f0df3e92 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -94,7 +94,7 @@ const _arg_desc = KW( :subplot_index => "Integer. Internal (not set by user). Specifies the index of this subplot in the Plot's `plt.subplot` list.", :colorbar_title => "String. Title of colorbar.", :framestyle => "Symbol. Style of the axes frame. Choose from $(_allFramestyles)", -:camera => "NTuple{2, Int(GR)/Real(Other)}. Sets the view angle (azimuthal, elevation) for 3D plots", +:camera => "NTuple{2, Real}. Sets the view angle (azimuthal, elevation) for 3D plots", # axis args :guide => "String. Axis guide (label).", diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 21d2c5db..01b9d6e6 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -751,7 +751,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end - GR.setspace(zmin, zmax, sp[:camera]...) + GR.setspace(zmin, zmax, map(Int,map(round,sp[:camera]))...) xtick = GR.tick(xmin, xmax) / 2 ytick = GR.tick(ymin, ymax) / 2 ztick = GR.tick(zmin, zmax) / 2 From a016b655f47a8d8d09ffba77b9f2fa5e9720acc8 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 7 Oct 2017 13:06:08 -0700 Subject: [PATCH 415/720] New docs page link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 72a82007..c107eaab 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ Plots is a plotting API and toolset. My goals with the package are: - **Lightweight**. Very few dependencies. - **Smart**. Attempts to figure out what you **want** it to do... not just what you **tell** it. -View the [full documentation](http://juliaplots.github.io). +View the [full documentation](docs.juliaplots.org/latest). From eda1ebe36becb9d9b3f4ce8565b65635ca945ab7 Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 7 Oct 2017 13:24:03 -0700 Subject: [PATCH 416/720] Fix docs link Ugh, flubbed that one. There's the `http://` --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c107eaab..ebafb2db 100644 --- a/README.md +++ b/README.md @@ -20,4 +20,4 @@ Plots is a plotting API and toolset. My goals with the package are: - **Lightweight**. Very few dependencies. - **Smart**. Attempts to figure out what you **want** it to do... not just what you **tell** it. -View the [full documentation](docs.juliaplots.org/latest). +View the [full documentation](http://docs.juliaplots.org/latest). From f8576c71350ccc43fb36cdbbfd431c37d2ff4973 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Mon, 9 Oct 2017 11:33:24 +0100 Subject: [PATCH 417/720] Remove :view alias for :camera attribute. --- src/args.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index 505b1d74..7632b5bf 100644 --- a/src/args.jl +++ b/src/args.jl @@ -533,7 +533,7 @@ add_aliases(:gridlinewidth, :gridwidth, :grid_linewidth, :grid_width, :gridlw, : add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, :gridls) add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor) -add_aliases(:camera, :cam, :view, :viewangle, :view_angle) +add_aliases(:camera, :cam, :viewangle, :view_angle) # add all pluralized forms to the _keyAliases dict for arg in keys(_series_defaults) From 6df2bc2790c8018db6eaf731ef08654199c29d64 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Mon, 9 Oct 2017 11:40:04 +0100 Subject: [PATCH 418/720] Clarify gr.jl setspace() rounding syntax. --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 01b9d6e6..5430f53b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -751,7 +751,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end - GR.setspace(zmin, zmax, map(Int,map(round,sp[:camera]))...) + GR.setspace(zmin, zmax, round.(Int, sp[:camera])...) xtick = GR.tick(xmin, xmax) / 2 ytick = GR.tick(ymin, ymax) / 2 ztick = GR.tick(zmin, zmax) / 2 From 55c968f1389fb9173ac62aa687f1b59a67fabbd5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 9 Oct 2017 17:13:44 +0200 Subject: [PATCH 419/720] fix marker_z for 3D plots - draw colorbar once per series --- src/backends/gr.jl | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d78aa804..6d41c547 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -342,10 +342,10 @@ function gr_draw_markers(series::Series, x, y, clims) mz = normalize_zvals(series[:marker_z], clims) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_draw_markers(series, x, y, series[:markersize], mz) - if hascolorbar(series[:subplot]) - GR.setscale(0) - gr_colorbar(series[:subplot], clims) - end + # if hascolorbar(series[:subplot]) + # GR.setscale(0) + # gr_colorbar(series[:subplot], clims) + # end end # --------------------------------------------------------- @@ -960,9 +960,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) GR.fillarea(fx, fy) end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - GR.settransparency(1) - cmap && gr_colorbar(sp, clims) end # draw the line(s) @@ -972,8 +969,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x[rng], y[rng]; arrowside = arrowside) end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - cmap && gr_colorbar(sp, clims) end end @@ -1021,7 +1016,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setfillcolorind(0) GR.surface(x, y, z, GR.OPTION_FILLED_MESH) end - cmap && gr_colorbar(sp) elseif st == :heatmap xmin, xmax, ymin, ymax = xy_lims @@ -1035,7 +1029,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, red(c) * 255) ), colors) w, h = length(x), length(y) GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) - cmap && gr_colorbar(sp, clims) elseif st in (:path3d, :scatter3d) # draw path @@ -1051,8 +1044,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) GR.polyline3d(x[rng], y[rng], z[rng]) end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - cmap && gr_colorbar(sp, clims) end end @@ -1128,8 +1119,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.polyline(xseg, yseg) end end - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - cmap && gr_colorbar(sp, clims) elseif st == :image @@ -1147,6 +1136,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) end + # draw the colorbar + if cmap && st != :contour # special colorbar with steps is drawn for contours + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + GR.settransparency(1) + gr_colorbar(sp, clims) + 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) From bac192d825ffd9b4dd21e8ccf3da268e02f5da58 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 9 Oct 2017 17:20:36 +0200 Subject: [PATCH 420/720] remove unnecessary lines --- src/backends/gr.jl | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6d41c547..d90aedf4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -342,10 +342,6 @@ function gr_draw_markers(series::Series, x, y, clims) mz = normalize_zvals(series[:marker_z], clims) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_draw_markers(series, x, y, series[:markersize], mz) - # if hascolorbar(series[:subplot]) - # GR.setscale(0) - # gr_colorbar(series[:subplot], clims) - # end end # --------------------------------------------------------- @@ -447,12 +443,6 @@ function gr_set_viewport_polar() end # add the colorbar -function gr_colorbar(sp::Subplot) - gr_set_viewport_cmap(sp) - GR.colorbar() - gr_set_viewport_plotarea() -end - function gr_colorbar(sp::Subplot, clims) xmin, xmax = gr_xy_axislims(sp)[1:2] gr_set_viewport_cmap(sp) From 08bdd11410955d56e4020480047854681aa1f7f3 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 9 Oct 2017 21:19:32 +0200 Subject: [PATCH 421/720] New spy implementation --- src/recipes.jl | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 109b7b05..97352505 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -945,23 +945,21 @@ end @recipe function f(::Type{Val{:spy}}, x,y,z) yflip := true aspect_ratio := 1 + rs, cs, zs = findnz(z.surf) - xlim := ignorenan_extrema(cs) - ylim := ignorenan_extrema(rs) - if plotattributes[:markershape] == :none - markershape := :circle + newz = fill(NaN, size(z)...) + + for i in eachindex(zs) + newz[rs[i],cs[i]] = zs[i] end - if plotattributes[:markersize] == default(:markersize) - markersize := 1 - end - markerstrokewidth := 0 - marker_z := zs - label := "" - x := cs - y := rs - z := nothing - seriestype := :scatter + + seriestype := :heatmap grid --> false + framestyle --> :box + + x := x + y := y + z := Surface(newz) () end From cc201ce4e7d760cb2526ecb20b4b291d81fb53df Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 10 Oct 2017 10:54:29 +0200 Subject: [PATCH 422/720] gr: fixed colorbar problem for flipped axes --- src/backends/gr.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index d78aa804..898729f6 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -458,6 +458,7 @@ function gr_colorbar(sp::Subplot, clims) gr_set_viewport_cmap(sp) l = zeros(Int32, 1, 256) l[1,:] = Int[round(Int, _i) for _i in linspace(1000, 1255, 256)] + GR.setscale(0) GR.setwindow(xmin, xmax, clims[1], clims[2]) GR.cellarray(xmin, xmax, clims[2], clims[1], 1, length(l), l) ztick = 0.5 * GR.tick(clims[1], clims[2]) From 9dcbc06b3d688e3a5fc8c3e4dbc38104f686ee00 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 10 Oct 2017 19:50:45 +0200 Subject: [PATCH 423/720] update version for tests --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index d59aa5fa..b9038d3d 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.12.4" +const _current_plots_version = v"0.13.1" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 979a846298114e9b5449b4481acab89b440678ff Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 10 Oct 2017 23:26:39 +0200 Subject: [PATCH 424/720] fix flip for GR --- src/axes.jl | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 6b437f22..2ba6b0ce 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -518,12 +518,16 @@ function axis_drawing_info(sp::Subplot) xborder_segs = Segments(2) yborder_segs = Segments(2) - if !(sp[:framestyle] == :none) + if sp[:framestyle] != :none # xaxis if xaxis[:showaxis] - sp[:framestyle] in (:grid, :origin, :zerolines) || push!(xaxis_segs, (xmin,ymin), (xmax,ymin)) # bottom spine / xaxis - if sp[:framestyle] in (:origin, :zerolines) - push!(xaxis_segs, (xmin, 0.0), (xmax, 0.0)) + if sp[:framestyle] != :grid + yval = if sp[:framestyle] in (:origin, :zerolines) + 0.0 + else + xor(xaxis[:mirror], yaxis[:flip]) ? ymax : ymin + end + push!(xaxis_segs, (xmin, yval), (xmax, yval)) # don't show the 0 tick label for the origin framestyle if sp[:framestyle] == :origin && length(xticks) > 1 showticks = xticks[1] .!= 0 @@ -545,7 +549,7 @@ function axis_drawing_info(sp::Subplot) tick_start, tick_stop = if sp[:framestyle] == :origin (0, t3) else - xaxis[:mirror] ? (ymax, t2) : (ymin, t1) + xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, t2) : (ymin, t1) end push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick end @@ -556,9 +560,13 @@ function axis_drawing_info(sp::Subplot) # yaxis if yaxis[:showaxis] - sp[:framestyle] in (:grid, :origin, :zerolines) || push!(yaxis_segs, (xmin,ymin), (xmin,ymax)) # left spine / yaxis - if sp[:framestyle] in (:origin, :zerolines) - push!(yaxis_segs, (0.0, ymin), (0.0, ymax)) + if sp[:framestyle] != :grid + xval = if sp[:framestyle] in (:origin, :zerolines) + 0.0 + else + xor(yaxis[:mirror], xaxis[:flip]) ? xmax : xmin + end + push!(yaxis_segs, (xval, ymin), (xval, ymax)) # don't show the 0 tick label for the origin framestyle if sp[:framestyle] == :origin && length(yticks) > 1 showticks = yticks[1] .!= 0 @@ -580,7 +588,7 @@ function axis_drawing_info(sp::Subplot) tick_start, tick_stop = if sp[:framestyle] == :origin (0, t3) else - yaxis[:mirror] ? (xmax, t2) : (xmin, t1) + xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, t2) : (xmin, t1) end push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick end From be55c1ad6f57c1e7ac150e40501e680fbd3149d1 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Tue, 10 Oct 2017 23:29:18 +0100 Subject: [PATCH 425/720] save svg plotlyjs --- src/backends/plotlyjs.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 0a2ad219..0776dbf1 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -85,7 +85,8 @@ end # ---------------------------------------------------------------- -function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) +function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) + prepare_output(plt) if isijulia() && !_use_remote[] write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o))) else @@ -98,6 +99,7 @@ function plotlyjs_save_hack(io::IO, plt::Plot{PlotlyJSBackend}, ext::String) PlotlyJS.savefig(plt.o, tmpfn) write(io, read(open(tmpfn))) end +_show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "svg") _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyJSBackend}) = plotlyjs_save_hack(io, plt, "png") _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") From 4c7ab232d56fbe98c62fed6f15f191d72b1d6ec3 Mon Sep 17 00:00:00 2001 From: Darwin Darakananda Date: Wed, 11 Oct 2017 10:25:54 -0700 Subject: [PATCH 426/720] Add (back?) ability to reset defaults --- src/args.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/args.jl b/src/args.jl index 3ea3efde..b7f0d278 100644 --- a/src/args.jl +++ b/src/args.jl @@ -393,6 +393,8 @@ const _all_defaults = KW[ _axis_defaults_byletter ] +const _initial_defaults = deepcopy(_all_defaults) + # to be able to reset font sizes to initial values const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefont].pointsize, :legendfont => _subplot_defaults[:legendfont].pointsize, @@ -588,6 +590,7 @@ function default(d::KW, k::Symbol) get(d, k, default(k)) end +reset_defaults() = foreach(merge!, _all_defaults, _initial_defaults) # ----------------------------------------------------------------------------- From 422988b3f6f005c178ed2530d6b4612ab9990b5c Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 13 Oct 2017 12:38:56 +0200 Subject: [PATCH 427/720] fix `weights` in `histogram` --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 97352505..8fb582ae 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -550,7 +550,7 @@ function _make_hist{N}(vs::NTuple{N,AbstractVector}, binning; normed = false, we edges = _hist_edges(vs, binning) h = float( weights == nothing ? StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) : - StatsBase.fit(StatsBase.Histogram, vs, weights, edges, closed = :left) + StatsBase.fit(StatsBase.Histogram, vs, StatsBase.Weights(weights), edges, closed = :left) ) normalize!(h, mode = _hist_norm_mode(normed)) end From 6db7116db9f4b8a56f00950a97add4590882d47f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 13 Oct 2017 17:08:26 +0200 Subject: [PATCH 428/720] add `weights` argument to histogram example --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index fabb368d..ed62e00e 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -145,7 +145,7 @@ PlotExample("Bar", PlotExample("Histogram", "", [:(begin - histogram(randn(1000), nbins=20) + histogram(randn(1000), bins = :scott, weights = repeat(1:5, outer = 200)) end)] ), From d8ba26f79074a6b927ea94e0b06d6c98712d51ef Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Sat, 14 Oct 2017 08:52:51 +0200 Subject: [PATCH 429/720] Don't copy input arguments into `d` --- src/series.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/series.jl b/src/series.jl index c0d7d4c2..5ad05fe5 100644 --- a/src/series.jl +++ b/src/series.jl @@ -75,17 +75,17 @@ end compute_x(x::Void, y::Void, z) = 1:size(z,1) compute_x(x::Void, y, z) = 1:size(y,1) compute_x(x::Function, y, z) = map(x, y) -compute_x(x, y, z) = copy(x) +compute_x(x, y, z) = x # compute_y(x::Void, y::Function, z) = error() compute_y(x::Void, y::Void, z) = 1:size(z,2) compute_y(x, y::Function, z) = map(y, x) -compute_y(x, y, z) = copy(y) +compute_y(x, y, z) = y compute_z(x, y, z::Function) = map(z, x, y) compute_z(x, y, z::AbstractMatrix) = Surface(z) compute_z(x, y, z::Void) = nothing -compute_z(x, y, z) = copy(z) +compute_z(x, y, z) = z nobigs(v::AVec{BigFloat}) = map(Float64, v) nobigs(v::AVec{BigInt}) = map(Int64, v) @@ -371,7 +371,7 @@ end end # try some intervals over which the function may be defined -function tryrange(F::AbstractArray, vec) +function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there From 735a45b4e96879c3ad5d498b2a9c2756c3e49e7e Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Sat, 14 Oct 2017 22:55:23 +0200 Subject: [PATCH 430/720] Revert "Don't copy input arguments - fix #1175" --- src/series.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/series.jl b/src/series.jl index 5ad05fe5..c0d7d4c2 100644 --- a/src/series.jl +++ b/src/series.jl @@ -75,17 +75,17 @@ end compute_x(x::Void, y::Void, z) = 1:size(z,1) compute_x(x::Void, y, z) = 1:size(y,1) compute_x(x::Function, y, z) = map(x, y) -compute_x(x, y, z) = x +compute_x(x, y, z) = copy(x) # compute_y(x::Void, y::Function, z) = error() compute_y(x::Void, y::Void, z) = 1:size(z,2) compute_y(x, y::Function, z) = map(y, x) -compute_y(x, y, z) = y +compute_y(x, y, z) = copy(y) compute_z(x, y, z::Function) = map(z, x, y) compute_z(x, y, z::AbstractMatrix) = Surface(z) compute_z(x, y, z::Void) = nothing -compute_z(x, y, z) = z +compute_z(x, y, z) = copy(z) nobigs(v::AVec{BigFloat}) = map(Float64, v) nobigs(v::AVec{BigInt}) = map(Int64, v) @@ -371,7 +371,7 @@ end end # try some intervals over which the function may be defined -function tryrange(F::AbstractArray, vec) +function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there From 8ea878a2a2ca67ad45002979fa0423ad921b0b77 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Sun, 15 Oct 2017 12:43:15 +0200 Subject: [PATCH 431/720] Fix appveyor badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebafb2db..16f70198 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Plots [![Build Status](https://travis-ci.org/JuliaPlots/Plots.jl.svg?branch=master)](https://travis-ci.org/JuliaPlots/Plots.jl) -[![Build status](https://ci.appveyor.com/api/projects/status/github/tbreloff/plots.jl?branch=master&svg=true)](https://ci.appveyor.com/project/tbreloff/plots-jl) +[![Build status](https://ci.appveyor.com/api/projects/status/github/juliaplots/plots.jl?branch=master&svg=true)](https://ci.appveyor.com/project/mkborregaard/plots-jl) [![Join the chat at https://gitter.im/tbreloff/Plots.jl](https://badges.gitter.im/tbreloff/Plots.jl.svg)](https://gitter.im/tbreloff/Plots.jl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) From 94c0957e11f3101c7af8881be70382cf35f1ce69 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 16 Oct 2017 18:04:46 +0200 Subject: [PATCH 432/720] draw colorbar in the end --- src/backends/gr.jl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9d9d6b32..96ca08f4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1128,13 +1128,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) end - # draw the colorbar - if cmap && st != :contour # special colorbar with steps is drawn for contours - gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - GR.settransparency(1) - gr_colorbar(sp, clims) - 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) @@ -1142,6 +1135,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_text(GR.wctondc(xi, yi)..., str) end + # draw the colorbar + if cmap && st != :contour # special colorbar with steps is drawn for contours + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) + GR.settransparency(1) + gr_colorbar(sp, clims) + end + GR.restorestate() end From 3ce71999e257cde2f9f24746323a2ddc00ab7c18 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 16 Oct 2017 21:24:13 +0200 Subject: [PATCH 433/720] spy recipe: change default color for matrices with unique values --- src/recipes.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 8fb582ae..5501351a 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -937,6 +937,8 @@ end mat = g.args[1] if length(unique(mat[mat .!= 0])) < 2 legend --> nothing + # revert the default gradient to have a darker (almost black) color in the default theme + seriescolor --> cgrad([cgrad()[0], cgrad()[1]]) end n,m = size(mat) Plots.SliceIt, 1:m, 1:n, Surface(mat) @@ -945,7 +947,7 @@ end @recipe function f(::Type{Val{:spy}}, x,y,z) yflip := true aspect_ratio := 1 - + rs, cs, zs = findnz(z.surf) newz = fill(NaN, size(z)...) From 2464d7bd9a9df7961599dc3e1c66bdaff404d14b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 16 Oct 2017 21:46:23 +0200 Subject: [PATCH 434/720] fix combination of box framestyle and flip on gr --- src/axes.jl | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 2ba6b0ce..25e45694 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -522,19 +522,19 @@ function axis_drawing_info(sp::Subplot) # xaxis if xaxis[:showaxis] if sp[:framestyle] != :grid - yval = if sp[:framestyle] in (:origin, :zerolines) - 0.0 + y1, y2 = if sp[:framestyle] in (:origin, :zerolines) + 0.0, 0.0 else - xor(xaxis[:mirror], yaxis[:flip]) ? ymax : ymin + xor(xaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax) end - push!(xaxis_segs, (xmin, yval), (xmax, yval)) + push!(xaxis_segs, (xmin, y1), (xmax, y1)) # don't show the 0 tick label for the origin framestyle if sp[:framestyle] == :origin && length(xticks) > 1 showticks = xticks[1] .!= 0 xticks = (xticks[1][showticks], xticks[2][showticks]) end end - sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin,ymax), (xmax,ymax)) # top spine + sp[:framestyle] in (:semi, :box) && push!(xborder_segs, (xmin, y2), (xmax, y2)) # top spine end if !(xaxis[:ticks] in (nothing, false)) f = scalefunc(yaxis[:scale]) @@ -561,19 +561,19 @@ function axis_drawing_info(sp::Subplot) # yaxis if yaxis[:showaxis] if sp[:framestyle] != :grid - xval = if sp[:framestyle] in (:origin, :zerolines) - 0.0 + x1, x2 = if sp[:framestyle] in (:origin, :zerolines) + 0.0, 0.0 else - xor(yaxis[:mirror], xaxis[:flip]) ? xmax : xmin + xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax) end - push!(yaxis_segs, (xval, ymin), (xval, ymax)) + push!(yaxis_segs, (x1, ymin), (x1, ymax)) # don't show the 0 tick label for the origin framestyle if sp[:framestyle] == :origin && length(yticks) > 1 showticks = yticks[1] .!= 0 yticks = (yticks[1][showticks], yticks[2][showticks]) end end - sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (xmax,ymin), (xmax,ymax)) # right spine + sp[:framestyle] in (:semi, :box) && push!(yborder_segs, (x2, ymin), (x2, ymax)) # right spine end if !(yaxis[:ticks] in (nothing, false)) f = scalefunc(xaxis[:scale]) From 7f7b543e1802aa85a4bc9c1069d9b9f0a00b5340 Mon Sep 17 00:00:00 2001 From: HMH Date: Mon, 16 Oct 2017 23:53:00 +0200 Subject: [PATCH 435/720] Use ffmpeg & palette to create gifs, closes #1050 First let ffmpeg generate a colorpalette so it uses the limited amount of colors available properly and only then create the actual gif using the generated palette. This replaces convert completely as it yields far worse results for long gifs and is considerably slower. --- src/animation.jl | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 4afa01cf..9e676f7c 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -64,35 +64,15 @@ gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim.dir, fn; kw...) mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim.dir, fn; kw...) mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn; kw...) -const _imagemagick_initialized = Ref(false) function buildanimation(animdir::AbstractString, fn::AbstractString; fps::Integer = 20, loop::Integer = 0) fn = abspath(fn) - try - if !_imagemagick_initialized[] - file = joinpath(Pkg.dir("ImageMagick"), "deps","deps.jl") - if isfile(file) && !haskey(ENV, "MAGICK_CONFIGURE_PATH") - include(file) - end - _imagemagick_initialized[] = true - end - # prefix = get(ENV, "MAGICK_CONFIGURE_PATH", "") - # high quality - speed = round(Int, 100 / fps) - run(`convert -delay $speed -loop $loop $(joinpath(animdir, "*.png")) -alpha off $fn`) - - catch err - warn("""Tried to create gif using convert (ImageMagick), but got error: $err - ImageMagick can be installed by executing `Pkg.add("ImageMagick")`. - You may also need to install the imagemagick c++ library through your operating system. - Will try ffmpeg, but it's lower quality...)""") - - # low quality - run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -y $fn`) - # run(`ffmpeg -v warning -i "fps=$fps,scale=320:-1:flags=lanczos"`) - end + # generate a colorpalette first so ffmpeg does not have to guess it + run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.png`) + # then apply the palette to get better results + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.png -lavfi paletteuse -y $fn`) info("Saved animation to ", fn) AnimatedGif(fn) From ef29b4a5b025d23bb232f85799a3811ed301ef8d Mon Sep 17 00:00:00 2001 From: "femtocleaner[bot]" Date: Tue, 17 Oct 2017 09:59:09 +0000 Subject: [PATCH 436/720] Fix deprecations --- src/Plots.jl | 48 +++++++------- src/animation.jl | 8 +-- src/args.jl | 6 +- src/axes.jl | 4 +- src/backends.jl | 6 +- src/backends/glvisualize.jl | 22 +++---- src/backends/gr.jl | 2 +- src/backends/hdf5.jl | 16 ++--- src/backends/inspectdr.jl | 12 ++-- src/backends/plotly.jl | 4 +- src/components.jl | 46 ++++++------- src/deprecated/backends/gadfly.jl | 8 +-- src/deprecated/backends/gadfly_shapes.jl | 2 +- src/deprecated/backends/immerse.jl | 4 +- src/deprecated/backends/qwt.jl | 4 +- src/deprecated/backends/winston.jl | 2 +- src/deprecated/colors.jl | 24 +++---- src/deprecated/series_args.jl | 10 +-- src/examples.jl | 2 +- src/layouts.jl | 14 ++-- src/output.jl | 6 +- src/pipeline.jl | 2 +- src/plot.jl | 2 +- src/recipes.jl | 40 ++++++------ src/series.jl | 60 ++++++++--------- src/subplots.jl | 2 +- src/types.jl | 16 ++--- src/utils.jl | 82 ++++++++++++------------ 28 files changed, 227 insertions(+), 227 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index e2ffa95c..d4f05cc5 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -110,13 +110,13 @@ export # --------------------------------------------------------- import NaNMath # define functions that ignores NaNs. To overcome the destructive effects of https://github.com/JuliaLang/julia/pull/12563 -ignorenan_minimum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.minimum(x) +ignorenan_minimum(x::AbstractArray{F}) where {F<:AbstractFloat} = NaNMath.minimum(x) ignorenan_minimum(x) = Base.minimum(x) -ignorenan_maximum{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.maximum(x) +ignorenan_maximum(x::AbstractArray{F}) where {F<:AbstractFloat} = NaNMath.maximum(x) ignorenan_maximum(x) = Base.maximum(x) -ignorenan_mean{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.mean(x) +ignorenan_mean(x::AbstractArray{F}) where {F<:AbstractFloat} = NaNMath.mean(x) ignorenan_mean(x) = Base.mean(x) -ignorenan_extrema{F<:AbstractFloat}(x::AbstractArray{F}) = NaNMath.extrema(x) +ignorenan_extrema(x::AbstractArray{F}) where {F<:AbstractFloat} = NaNMath.extrema(x) ignorenan_extrema(x) = Base.extrema(x) # --------------------------------------------------------- @@ -215,13 +215,13 @@ xlabel!(s::AbstractString; kw...) = plot!(; xlabel = s, kw...) ylabel!(s::AbstractString; kw...) = plot!(; ylabel = s, kw...) "Set xlims for an existing plot" -xlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; xlims = lims, kw...) +xlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; xlims = lims, kw...) "Set ylims for an existing plot" -ylims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; ylims = lims, kw...) +ylims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; ylims = lims, kw...) "Set zlims for an existing plot" -zlims!{T<:Real,S<:Real}(lims::Tuple{T,S}; kw...) = plot!(; zlims = lims, kw...) +zlims!(lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(; zlims = lims, kw...) xlims!(xmin::Real, xmax::Real; kw...) = plot!(; xlims = (xmin,xmax), kw...) ylims!(ymin::Real, ymax::Real; kw...) = plot!(; ylims = (ymin,ymax), kw...) @@ -229,19 +229,19 @@ zlims!(zmin::Real, zmax::Real; kw...) = plot!(; zlims = (zmi "Set xticks for an existing plot" -xticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; xticks = v, kw...) +xticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; xticks = v, kw...) "Set yticks for an existing plot" -yticks!{T<:Real}(v::AVec{T}; kw...) = plot!(; yticks = v, kw...) +yticks!(v::AVec{T}; kw...) where {T<:Real} = plot!(; yticks = v, kw...) -xticks!{T<:Real,S<:AbstractString}( - ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; xticks = (ticks,labels), kw...) -yticks!{T<:Real,S<:AbstractString}( - ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(; yticks = (ticks,labels), kw...) +xticks!( +ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; xticks = (ticks,labels), kw...) +yticks!( +ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(; yticks = (ticks,labels), kw...) "Add annotations to an existing plot" annotate!(anns...; kw...) = plot!(; annotation = anns, kw...) -annotate!{T<:Tuple}(anns::AVec{T}; kw...) = plot!(; annotation = anns, kw...) +annotate!(anns::AVec{T}; kw...) where {T<:Tuple} = plot!(; annotation = anns, kw...) "Flip the current plots' x axis" xflip!(flip::Bool = true; kw...) = plot!(; xflip = flip, kw...) @@ -261,22 +261,22 @@ let PlotOrSubplot = Union{Plot, Subplot} title!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; title = s, kw...) xlabel!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; xlabel = s, kw...) ylabel!(plt::PlotOrSubplot, s::AbstractString; kw...) = plot!(plt; ylabel = s, kw...) - xlims!{T<:Real,S<:Real}(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) = plot!(plt; xlims = lims, kw...) - ylims!{T<:Real,S<:Real}(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) = plot!(plt; ylims = lims, kw...) - zlims!{T<:Real,S<:Real}(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) = plot!(plt; zlims = lims, kw...) + xlims!(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(plt; xlims = lims, kw...) + ylims!(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(plt; ylims = lims, kw...) + zlims!(plt::PlotOrSubplot, lims::Tuple{T,S}; kw...) where {T<:Real,S<:Real} = plot!(plt; zlims = lims, kw...) xlims!(plt::PlotOrSubplot, xmin::Real, xmax::Real; kw...) = plot!(plt; xlims = (xmin,xmax), kw...) ylims!(plt::PlotOrSubplot, ymin::Real, ymax::Real; kw...) = plot!(plt; ylims = (ymin,ymax), kw...) zlims!(plt::PlotOrSubplot, zmin::Real, zmax::Real; kw...) = plot!(plt; zlims = (zmin,zmax), kw...) - xticks!{T<:Real}(plt::PlotOrSubplot, ticks::AVec{T}; kw...) = plot!(plt; xticks = ticks, kw...) - yticks!{T<:Real}(plt::PlotOrSubplot, ticks::AVec{T}; kw...) = plot!(plt; yticks = ticks, kw...) - xticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot, - ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; xticks = (ticks,labels), kw...) - yticks!{T<:Real,S<:AbstractString}(plt::PlotOrSubplot, - ticks::AVec{T}, labels::AVec{S}; kw...) = plot!(plt; yticks = (ticks,labels), kw...) + xticks!(plt::PlotOrSubplot, ticks::AVec{T}; kw...) where {T<:Real} = plot!(plt; xticks = ticks, kw...) + yticks!(plt::PlotOrSubplot, ticks::AVec{T}; kw...) where {T<:Real} = plot!(plt; yticks = ticks, kw...) + xticks!(plt::PlotOrSubplot, + ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; xticks = (ticks,labels), kw...) + yticks!(plt::PlotOrSubplot, + ticks::AVec{T}, labels::AVec{S}; kw...) where {T<:Real,S<:AbstractString} = plot!(plt; yticks = (ticks,labels), kw...) xgrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; xgrid = args, kw...) ygrid!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; ygrid = args, kw...) annotate!(plt::PlotOrSubplot, anns...; kw...) = plot!(plt; annotation = anns, kw...) - annotate!{T<:Tuple}(plt::PlotOrSubplot, anns::AVec{T}; kw...) = plot!(plt; annotation = anns, kw...) + annotate!(plt::PlotOrSubplot, anns::AVec{T}; kw...) where {T<:Tuple} = plot!(plt; annotation = anns, kw...) xflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; xflip = flip, kw...) yflip!(plt::PlotOrSubplot, flip::Bool = true; kw...) = plot!(plt; yflip = flip, kw...) xaxis!(plt::PlotOrSubplot, args...; kw...) = plot!(plt; xaxis = args, kw...) diff --git a/src/animation.jl b/src/animation.jl index 4afa01cf..b7a13684 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -1,5 +1,5 @@ "Represents an animation object" -immutable Animation +struct Animation dir::String frames::Vector{String} end @@ -14,7 +14,7 @@ end Add a plot (the current plot if not specified) to an existing animation """ -function frame{P<:AbstractPlot}(anim::Animation, plt::P=current()) +function frame(anim::Animation, plt::P=current()) where P<:AbstractPlot i = length(anim.frames) + 1 filename = @sprintf("%06d.png", i) png(plt, joinpath(anim.dir, filename)) @@ -25,7 +25,7 @@ giffn() = (isijulia() ? "tmp.gif" : tempname()*".gif") movfn() = (isijulia() ? "tmp.mov" : tempname()*".mov") mp4fn() = (isijulia() ? "tmp.mp4" : tempname()*".mp4") -type FrameIterator +mutable struct FrameIterator itr every::Int kw @@ -54,7 +54,7 @@ end # ----------------------------------------------- "Wraps the location of an animated gif so that it can be displayed" -immutable AnimatedGif +struct AnimatedGif filename::String end diff --git a/src/args.jl b/src/args.jl index f049f68f..81cf03f8 100644 --- a/src/args.jl +++ b/src/args.jl @@ -889,7 +889,7 @@ end # ----------------------------------------------------------------------------- "A special type that will break up incoming data into groups, and allow for easier creation of grouped plots" -type GroupBy +mutable struct GroupBy groupLabels::Vector # length == numGroups groupIds::Vector{Vector{Int}} # list of indices for each group end @@ -916,7 +916,7 @@ function extractGroupArgs(vs::Tuple, args...) end # expecting a mapping of "group label" to "group indices" -function extractGroupArgs{T, V<:AVec{Int}}(idxmap::Dict{T,V}, args...) +function extractGroupArgs(idxmap::Dict{T,V}, args...) where {T, V<:AVec{Int}} groupLabels = sortedkeys(idxmap) groupIds = Vector{Int}[collect(idxmap[k]) for k in groupLabels] GroupBy(groupLabels, groupIds) @@ -1007,7 +1007,7 @@ function convertLegendValue(val::Symbol) end convertLegendValue(val::Bool) = val ? :best : :none convertLegendValue(val::Void) = :none -convertLegendValue{S<:Real, T<:Real}(v::Tuple{S,T}) = v +convertLegendValue(v::Tuple{S,T}) where {S<:Real, T<:Real} = v convertLegendValue(v::AbstractArray) = map(convertLegendValue, v) # ----------------------------------------------------------------------------- diff --git a/src/axes.jl b/src/axes.jl index 25e45694..4288cde3 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -293,13 +293,13 @@ expand_extrema!(axis::Axis, ::Void) = axis[:extrema] expand_extrema!(axis::Axis, ::Bool) = axis[:extrema] -function expand_extrema!{MIN<:Number,MAX<:Number}(axis::Axis, v::Tuple{MIN,MAX}) +function expand_extrema!(axis::Axis, v::Tuple{MIN,MAX}) where {MIN<:Number,MAX<:Number} ex = axis[:extrema] ex.emin = NaNMath.min(v[1], ex.emin) ex.emax = NaNMath.max(v[2], ex.emax) ex end -function expand_extrema!{N<:Number}(axis::Axis, v::AVec{N}) +function expand_extrema!(axis::Axis, v::AVec{N}) where N<:Number ex = axis[:extrema] for vi in v expand_extrema!(ex, vi) diff --git a/src/backends.jl b/src/backends.jl index b445807c..1dd5d8ad 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -1,5 +1,5 @@ -immutable NoBackend <: AbstractBackend end +struct NoBackend <: AbstractBackend end const _backendType = Dict{Symbol, DataType}(:none => NoBackend) const _backendSymbol = Dict{DataType, Symbol}(NoBackend => :none) @@ -18,7 +18,7 @@ macro init_backend(s) sym = Symbol(str) T = Symbol(string(s) * "Backend") esc(quote - immutable $T <: AbstractBackend end + struct $T <: AbstractBackend end export $sym $sym(; kw...) = (default(; kw...); backend(Symbol($str))) backend_name(::$T) = Symbol($str) @@ -123,7 +123,7 @@ _update_plot_object(plt::Plot) = nothing # --------------------------------------------------------- -type CurrentBackend +mutable struct CurrentBackend sym::Symbol pkg::AbstractBackend end diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index bbd5605a..716ce78a 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -69,9 +69,9 @@ function _initialize_backend(::GLVisualizeBackend; kw...) import GLVisualize: visualize import Plots.GL import UnicodeFun - Plots.slice_arg{C<:Colorant}(img::Matrix{C}, idx::Int) = img + Plots.slice_arg(img::Matrix{C}, idx::Int) where {C<:Colorant} = img is_marker_supported(::GLVisualizeBackend, shape::GLVisualize.AllPrimitives) = true - is_marker_supported{C<:Colorant}(::GLVisualizeBackend, shape::Union{Vector{Matrix{C}}, Matrix{C}}) = true + is_marker_supported(::GLVisualizeBackend, shape::Union{Vector{Matrix{C}}, Matrix{C}}) where {C<:Colorant} = true is_marker_supported(::GLVisualizeBackend, shape::Shape) = true const GL = Plots end @@ -214,13 +214,13 @@ function extract_limits(sp, d, kw_args) nothing end -to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vec::T) = vec -to_vec{T <: StaticArrays.StaticVector}(::Type{T}, s::Number) = T(s) +to_vec(::Type{T}, vec::T) where {T <: StaticArrays.StaticVector} = vec +to_vec(::Type{T}, s::Number) where {T <: StaticArrays.StaticVector} = T(s) -to_vec{T <: StaticArrays.StaticVector{2}}(::Type{T}, vec::StaticArrays.StaticVector{3}) = T(vec[1], vec[2]) -to_vec{T <: StaticArrays.StaticVector{3}}(::Type{T}, vec::StaticArrays.StaticVector{2}) = T(vec[1], vec[2], 0) +to_vec(::Type{T}, vec::StaticArrays.StaticVector{3}) where {T <: StaticArrays.StaticVector{2}} = T(vec[1], vec[2]) +to_vec(::Type{T}, vec::StaticArrays.StaticVector{2}) where {T <: StaticArrays.StaticVector{3}} = T(vec[1], vec[2], 0) -to_vec{T <: StaticArrays.StaticVector}(::Type{T}, vecs::AbstractVector) = map(x-> to_vec(T, x), vecs) +to_vec(::Type{T}, vecs::AbstractVector) where {T <: StaticArrays.StaticVector} = map(x-> to_vec(T, x), vecs) function extract_marker(d, kw_args) dim = Plots.is3d(d) ? 3 : 2 @@ -275,7 +275,7 @@ end function extract_surface(d) map(_extract_surface, (d[:x], d[:y], d[:z])) end -function topoints{P}(::Type{P}, array) +function topoints(::Type{P}, array) where P [P(x) for x in zip(array...)] end function extract_points(d) @@ -283,7 +283,7 @@ function extract_points(d) array = (d[:x], d[:y], d[:z])[1:dim] topoints(Point{dim, Float32}, array) end -function make_gradient{C <: Colorant}(grad::Vector{C}) +function make_gradient(grad::Vector{C}) where C <: Colorant grad end function make_gradient(grad::ColorGradient) @@ -338,7 +338,7 @@ function extract_color(d, sym) end gl_color(c::PlotUtils.ColorGradient) = c.colors -gl_color{T<:Colorant}(c::Vector{T}) = c +gl_color(c::Vector{T}) where {T<:Colorant} = c gl_color(c::RGBA{Float32}) = c gl_color(c::Colorant) = RGBA{Float32}(c) @@ -1212,7 +1212,7 @@ function gl_image(img, kw_args) visualize(img, Style(:default), kw_args) end -function handle_segment{P}(lines, line_segments, points::Vector{P}, segment) +function handle_segment(lines, line_segments, points::Vector{P}, segment) where P (isempty(segment) || length(segment) < 2) && return if length(segment) == 2 append!(line_segments, view(points, segment)) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 96ca08f4..791055ed 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -482,7 +482,7 @@ function gr_legend_pos(s::Symbol,w,h) (xpos,ypos) end -function gr_legend_pos{S<:Real, T<:Real}(v::Tuple{S,T},w,h) +function gr_legend_pos(v::Tuple{S,T},w,h) where {S<:Real, T<:Real} xpos = v[1] * (viewport_plotarea[2] - viewport_plotarea[1]) + viewport_plotarea[1] ypos = v[2] * (viewport_plotarea[4] - viewport_plotarea[3]) + viewport_plotarea[3] (xpos,ypos) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index a3a200ad..3adc912a 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -32,10 +32,10 @@ Read from .hdf5 file using: import FixedPointNumbers: N0f8 #In core Julia #Dispatch types: -immutable HDF5PlotNative; end #Indentifies a data element that can natively be handled by HDF5 -immutable HDF5CTuple; end #Identifies a "complex" tuple structure +struct HDF5PlotNative; end #Indentifies a data element that can natively be handled by HDF5 +struct HDF5CTuple; end #Identifies a "complex" tuple structure -type HDF5Plot_PlotRef +mutable struct HDF5Plot_PlotRef ref::Union{Plot, Void} end @@ -276,11 +276,11 @@ function _hdf5plot_overwritetype(grp, T::Type) #Write directly to group HDF5.a_delete(grp, _hdf5plot_datatypeid) HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) end -function _hdf5plot_writetype{T<:Any}(grp, ::Type{Array{T}}) +function _hdf5plot_writetype(grp, ::Type{Array{T}}) where T<:Any tstr = HDF5PLOT_MAP_TELEM2STR[Array] #ANY HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) end -function _hdf5plot_writetype{T<:BoundingBox}(grp, ::Type{T}) +function _hdf5plot_writetype(grp, ::Type{T}) where T<:BoundingBox tstr = HDF5PLOT_MAP_TELEM2STR[BoundingBox] HDF5.a_write(grp, _hdf5plot_datatypeid, tstr) end @@ -305,7 +305,7 @@ function _hdf5plot_gwrite(grp, k::String, v) #Default grp[k] = v _hdf5plot_writetype(grp, k, HDF5PlotNative) end -function _hdf5plot_gwrite{T<:Number}(grp, k::String, v::Array{T}) #Default for arrays +function _hdf5plot_gwrite(grp, k::String, v::Array{T}) where T<:Number #Default for arrays grp[k] = v _hdf5plot_writetype(grp, k, HDF5PlotNative) end @@ -355,7 +355,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Colorant) _hdf5plot_gwrite(grp, k, ARGB{N0f8}(v)) end #Custom vector (when not using simple numeric type): -function _hdf5plot_gwritearray{T}(grp, k::String, v::Array{T}) +function _hdf5plot_gwritearray(grp, k::String, v::Array{T}) where T if "annotations" == k; return #Hack. Does not yet support annotations. end @@ -380,7 +380,7 @@ function _hdf5plot_gwrite(grp, k::String, v::Extrema) grp[k] = [v.emin, v.emax] _hdf5plot_writetype(grp, k, Extrema) end -function _hdf5plot_gwrite{T}(grp, k::String, v::Length{T}) +function _hdf5plot_gwrite(grp, k::String, v::Length{T}) where T grp[k] = v.value _hdf5plot_writetype(grp, k, [HDF5PLOT_MAP_TELEM2STR[Length], string(T)]) end diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index a8224634..65f019a0 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -131,7 +131,7 @@ end function _inspectdr_getscale(s::Symbol, yaxis::Bool) #TODO: Support :asinh, :sqrt - kwargs = yaxis? (:tgtmajor=>8, :tgtminor=>2): () #More grid lines on y-axis + kwargs = yaxis ? (:tgtmajor=>8, :tgtminor=>2) : () #More grid lines on y-axis if :log2 == s return InspectDR.AxisScale(:log2; kwargs...) elseif :log10 == s @@ -163,7 +163,7 @@ function _initialize_backend(::InspectDRBackend; kw...) 2*InspectDR.GLYPH_SQUARE.x, InspectDR.GLYPH_SQUARE.y ) - type InspecDRPlotRef + mutable struct InspecDRPlotRef mplot::Union{Void, InspectDR.Multiplot} gui::Union{Void, InspectDR.GtkPlot} end @@ -172,7 +172,7 @@ function _initialize_backend(::InspectDRBackend; kw...) _inspectdr_getmplot(r::InspecDRPlotRef) = r.mplot _inspectdr_getgui(::Any) = nothing - _inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed? nothing: gplot) + _inspectdr_getgui(gplot::InspectDR.GtkPlot) = (gplot.destroyed ? nothing : gplot) _inspectdr_getgui(r::InspecDRPlotRef) = _inspectdr_getgui(r.gui) end end @@ -235,7 +235,7 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) #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 + _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: @@ -278,7 +278,7 @@ For st in :shape: end end - i = (nmax >= 2? div(nmax, 2): nmax) #Must pick one set of colors for legend + 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)) @@ -296,7 +296,7 @@ For st in :shape: #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]) + _style = (0==linewidth ? :none : series[:linestyle]) wfrm = InspectDR.add(plot, x, y, id=series[:label]) wfrm.line = InspectDR.line( style = _style, diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index c67511d2..f5ee90fa 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -122,7 +122,7 @@ const _plotly_legend_pos = KW( ) plotly_legend_pos(pos::Symbol) = get(_plotly_legend_pos, pos, [1.,1.]) -plotly_legend_pos{S<:Real, T<:Real}(v::Tuple{S,T}) = v +plotly_legend_pos(v::Tuple{S,T}) where {S<:Real, T<:Real} = v function plotly_font(font::Font, color = font.color) KW( @@ -441,7 +441,7 @@ end plotly_data(v) = collect(v) plotly_data(surf::Surface) = surf.surf -plotly_data{R<:Rational}(v::AbstractArray{R}) = float(v) +plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v) plotly_surface_data(series::Series, a::AbstractVector) = a plotly_surface_data(series::Series, a::AbstractMatrix) = transpose_z(series, a, false) diff --git a/src/components.jl b/src/components.jl index eba135c2..25784f1e 100644 --- a/src/components.jl +++ b/src/components.jl @@ -11,7 +11,7 @@ compute_angle(v::P2) = (angle = atan2(v[2], v[1]); angle < 0 ? 2π - angle : ang # ------------------------------------------------------------- -immutable Shape +struct Shape x::Vector{Float64} y::Vector{Float64} # function Shape(x::AVec, y::AVec) @@ -246,7 +246,7 @@ end # ----------------------------------------------------------------------- -type Font +mutable struct Font family::AbstractString pointsize::Int halign::Symbol @@ -336,7 +336,7 @@ function scalefontsizes() end "Wrap a string with font info" -immutable PlotText +struct PlotText str::AbstractString font::Font end @@ -359,7 +359,7 @@ Base.length(t::PlotText) = length(t.str) # ----------------------------------------------------------------------- -immutable Stroke +struct Stroke width color alpha @@ -401,7 +401,7 @@ function stroke(args...; alpha = nothing) end -immutable Brush +struct Brush size # fillrange, markersize, or any other sizey attribute color alpha @@ -434,7 +434,7 @@ end # ----------------------------------------------------------------------- -type SeriesAnnotations +mutable struct SeriesAnnotations strs::AbstractVector # the labels/names font::Font baseshape::Nullable @@ -513,7 +513,7 @@ function series_annotations_shapes!(series::Series, scaletype::Symbol = :pixels) return end -type EachAnn +mutable struct EachAnn anns x y @@ -538,12 +538,12 @@ annotations(sa::SeriesAnnotations) = sa # ----------------------------------------------------------------------- "type which represents z-values for colors and sizes (and anything else that might come up)" -immutable ZValues +struct ZValues values::Vector{Float64} zrange::Tuple{Float64,Float64} end -function zvalues{T<:Real}(values::AVec{T}, zrange::Tuple{T,T} = (ignorenan_minimum(values), ignorenan_maximum(values))) +function zvalues(values::AVec{T}, zrange::Tuple{T,T} = (ignorenan_minimum(values), ignorenan_maximum(values))) where T<:Real ZValues(collect(float(values)), map(Float64, zrange)) end @@ -552,7 +552,7 @@ end abstract type AbstractSurface end "represents a contour or surface mesh" -immutable Surface{M<:AMat} <: AbstractSurface +struct Surface{M<:AMat} <: AbstractSurface surf::M end @@ -564,7 +564,7 @@ for f in (:length, :size) @eval Base.$f(surf::Surface, args...) = $f(surf.surf, args...) end Base.copy(surf::Surface) = Surface(copy(surf.surf)) -Base.eltype{T}(surf::Surface{T}) = eltype(T) +Base.eltype(surf::Surface{T}) where {T} = eltype(T) function expand_extrema!(a::Axis, surf::Surface) ex = a[:extrema] @@ -575,7 +575,7 @@ function expand_extrema!(a::Axis, surf::Surface) end "For the case of representing a surface as a function of x/y... can possibly avoid allocations." -immutable SurfaceFunction <: AbstractSurface +struct SurfaceFunction <: AbstractSurface f::Function end @@ -585,19 +585,19 @@ end # # I don't want to clash with ValidatedNumerics, but this would be nice: # ..(a::T, b::T) = (a,b) -immutable Volume{T} +struct Volume{T} v::Array{T,3} x_extents::Tuple{T,T} y_extents::Tuple{T,T} z_extents::Tuple{T,T} end -default_extents{T}(::Type{T}) = (zero(T), one(T)) +default_extents(::Type{T}) where {T} = (zero(T), one(T)) -function Volume{T}(v::Array{T,3}, - x_extents = default_extents(T), - y_extents = default_extents(T), - z_extents = default_extents(T)) +function Volume(v::Array{T,3}, + x_extents = default_extents(T), + y_extents = default_extents(T), + z_extents = default_extents(T)) where T Volume(v, x_extents, y_extents, z_extents) end @@ -605,13 +605,13 @@ Base.Array(vol::Volume) = vol.v for f in (:length, :size) @eval Base.$f(vol::Volume, args...) = $f(vol.v, args...) end -Base.copy{T}(vol::Volume{T}) = Volume{T}(copy(vol.v), vol.x_extents, vol.y_extents, vol.z_extents) -Base.eltype{T}(vol::Volume{T}) = T +Base.copy(vol::Volume{T}) where {T} = Volume{T}(copy(vol.v), vol.x_extents, vol.y_extents, vol.z_extents) +Base.eltype(vol::Volume{T}) where {T} = T # ----------------------------------------------------------------------- # style is :open or :closed (for now) -immutable Arrow +struct Arrow style::Symbol side::Symbol # :head (default), :tail, or :both headlength::Float64 @@ -673,14 +673,14 @@ end # ----------------------------------------------------------------------- "Represents data values with formatting that should apply to the tick labels." -immutable Formatted{T} +struct Formatted{T} data::T formatter::Function end # ----------------------------------------------------------------------- "create a BezierCurve for plotting" -type BezierCurve{T <: FixedSizeArrays.Vec} +mutable struct BezierCurve{T <: FixedSizeArrays.Vec} control_points::Vector{T} end diff --git a/src/deprecated/backends/gadfly.jl b/src/deprecated/backends/gadfly.jl index bb501db2..53453b9e 100644 --- a/src/deprecated/backends/gadfly.jl +++ b/src/deprecated/backends/gadfly.jl @@ -558,7 +558,7 @@ function createGadflyAnnotationObject(x, y, txt::PlotText) )) end -function _add_annotations{X,Y,V}(plt::Plot{GadflyBackend}, anns::AVec{Tuple{X,Y,V}}) +function _add_annotations(plt::Plot{GadflyBackend}, anns::AVec{Tuple{X,Y,V}}) where {X,Y,V} for ann in anns push!(plt.o.guides, createGadflyAnnotationObject(ann...)) end @@ -614,7 +614,7 @@ function getxy(plt::Plot{GadflyBackend}, i::Integer) mapping[:x], mapping[:y] end -function setxy!{X,Y}(plt::Plot{GadflyBackend}, xy::Tuple{X,Y}, i::Integer) +function setxy!(plt::Plot{GadflyBackend}, xy::Tuple{X,Y}, i::Integer) where {X,Y} for mapping in getGadflyMappings(plt, i) mapping[:x], mapping[:y] = xy end @@ -677,7 +677,7 @@ setGadflyDisplaySize(plt::Plot) = setGadflyDisplaySize(plt.attr[:size]...) # ------------------------------------------------------------------------- -function doshow{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, func, plt::AbstractPlot{P}) +function doshow(io::IO, func, plt::AbstractPlot{P}) where P<:Union{GadflyBackend,ImmerseBackend} gplt = getGadflyContext(plt) setGadflyDisplaySize(plt) Gadfly.draw(func(io, Compose.default_graphic_width, Compose.default_graphic_height), gplt) @@ -692,7 +692,7 @@ getGadflyWriteFunc(::MIME"application/x-tex") = Gadfly.PGF getGadflyWriteFunc(m::MIME) = error("Unsupported in Gadfly/Immerse: ", m) for mime in (MIME"image/png", MIME"image/svg+xml", MIME"application/pdf", MIME"application/postscript", MIME"application/x-tex") - @eval function Base.show{P<:Union{GadflyBackend,ImmerseBackend}}(io::IO, ::$mime, plt::AbstractPlot{P}) + @eval function Base.show(io::IO, ::$mime, plt::AbstractPlot{P}) where P<:Union{GadflyBackend,ImmerseBackend} func = getGadflyWriteFunc($mime()) doshow(io, func, plt) end diff --git a/src/deprecated/backends/gadfly_shapes.jl b/src/deprecated/backends/gadfly_shapes.jl index 9c70c90c..1a818993 100644 --- a/src/deprecated/backends/gadfly_shapes.jl +++ b/src/deprecated/backends/gadfly_shapes.jl @@ -2,7 +2,7 @@ # Geometry which displays arbitrary shapes at given (x, y) positions. # note: vertices is a list of shapes -immutable ShapeGeometry <: Gadfly.GeometryElement +struct ShapeGeometry <: Gadfly.GeometryElement vertices::AbstractVector #{Tuple{Float64,Float64}} tag::Symbol diff --git a/src/deprecated/backends/immerse.jl b/src/deprecated/backends/immerse.jl index b8679cf3..58950480 100644 --- a/src/deprecated/backends/immerse.jl +++ b/src/deprecated/backends/immerse.jl @@ -61,7 +61,7 @@ end # ---------------------------------------------------------------- -function _add_annotations{X,Y,V}(plt::Plot{ImmerseBackend}, anns::AVec{Tuple{X,Y,V}}) +function _add_annotations(plt::Plot{ImmerseBackend}, anns::AVec{Tuple{X,Y,V}}) where {X,Y,V} for ann in anns push!(getGadflyContext(plt).guides, createGadflyAnnotationObject(ann...)) end @@ -76,7 +76,7 @@ function getxy(plt::Plot{ImmerseBackend}, i::Integer) mapping[:x], mapping[:y] end -function setxy!{X,Y}(plt::Plot{ImmerseBackend}, xy::Tuple{X,Y}, i::Integer) +function setxy!(plt::Plot{ImmerseBackend}, xy::Tuple{X,Y}, i::Integer) where {X,Y} for mapping in getGadflyMappings(plt, i) mapping[:x], mapping[:y] = xy end diff --git a/src/deprecated/backends/qwt.jl b/src/deprecated/backends/qwt.jl index 2173c599..6bffd322 100644 --- a/src/deprecated/backends/qwt.jl +++ b/src/deprecated/backends/qwt.jl @@ -218,7 +218,7 @@ function createQwtAnnotation(plt::Plot, x, y, val::AbstractString) marker[:attach](plt.o.widget) end -function _add_annotations{X,Y,V}(plt::Plot{QwtBackend}, anns::AVec{Tuple{X,Y,V}}) +function _add_annotations(plt::Plot{QwtBackend}, anns::AVec{Tuple{X,Y,V}}) where {X,Y,V} for ann in anns createQwtAnnotation(plt, ann...) end @@ -233,7 +233,7 @@ function getxy(plt::Plot{QwtBackend}, i::Int) series.x, series.y end -function setxy!{X,Y}(plt::Plot{QwtBackend}, xy::Tuple{X,Y}, i::Integer) +function setxy!(plt::Plot{QwtBackend}, xy::Tuple{X,Y}, i::Integer) where {X,Y} series = plt.o.lines[i] series.x, series.y = xy plt diff --git a/src/deprecated/backends/winston.jl b/src/deprecated/backends/winston.jl index 8e7b97c7..22694be8 100644 --- a/src/deprecated/backends/winston.jl +++ b/src/deprecated/backends/winston.jl @@ -217,7 +217,7 @@ function createWinstonAnnotationObject(plt::Plot{WinstonBackend}, x, y, val::Abs Winston.text(x, y, val) end -function _add_annotations{X,Y,V}(plt::Plot{WinstonBackend}, anns::AVec{Tuple{X,Y,V}}) +function _add_annotations(plt::Plot{WinstonBackend}, anns::AVec{Tuple{X,Y,V}}) where {X,Y,V} for ann in anns createWinstonAnnotationObject(plt, ann...) end diff --git a/src/deprecated/colors.jl b/src/deprecated/colors.jl index f73d5db6..8247529a 100644 --- a/src/deprecated/colors.jl +++ b/src/deprecated/colors.jl @@ -34,9 +34,9 @@ getColorVector(scheme::ColorScheme) = [getColor(scheme)] colorscheme(scheme::ColorScheme) = scheme colorscheme(s::AbstractString; kw...) = colorscheme(Symbol(s); kw...) colorscheme(s::Symbol; kw...) = haskey(_gradients, s) ? ColorGradient(s; kw...) : ColorWrapper(convertColor(s); kw...) -colorscheme{T<:Real}(s::Symbol, vals::AVec{T}; kw...) = ColorGradient(s, vals; kw...) +colorscheme(s::Symbol, vals::AVec{T}; kw...) where {T<:Real} = ColorGradient(s, vals; kw...) colorscheme(cs::AVec, vs::AVec; kw...) = ColorGradient(cs, vs; kw...) -colorscheme{T<:Colorant}(cs::AVec{T}; kw...) = ColorGradient(cs; kw...) +colorscheme(cs::AVec{T}; kw...) where {T<:Colorant} = ColorGradient(cs; kw...) colorscheme(f::Function; kw...) = ColorFunction(f; kw...) colorscheme(v::AVec; kw...) = ColorVector(v; kw...) colorscheme(m::AMat; kw...) = size(m,1) == 1 ? map(c->colorscheme(c; kw...), m) : [colorscheme(m[:,i]; kw...) for i in 1:size(m,2)]' @@ -98,7 +98,7 @@ const _gradients = KW( :lighttest => map(c -> lighten(c, 0.3), _testColors), ) -function register_gradient_colors{C<:Colorant}(name::Symbol, colors::AVec{C}) +function register_gradient_colors(name::Symbol, colors::AVec{C}) where C<:Colorant _gradients[name] = colors end @@ -109,11 +109,11 @@ default_gradient() = ColorGradient(:inferno) # -------------------------------------------------------------- "Continuous gradient between values. Wraps a list of bounding colors and the values they represent." -immutable ColorGradient <: ColorScheme +struct ColorGradient <: ColorScheme colors::Vector values::Vector - function ColorGradient{S<:Real}(cs::AVec, vals::AVec{S} = linspace(0, 1, length(cs)); alpha = nothing) + function ColorGradient(cs::AVec, vals::AVec{S} = linspace(0, 1, length(cs)); alpha = nothing) where S<:Real if length(cs) == length(vals) return new(convertColor(cs,alpha), collect(vals)) end @@ -138,7 +138,7 @@ Base.getindex(cs::ColorGradient, z::Number) = getColorZ(cs, z) # create a gradient from a symbol (blues, reds, etc) and vector of boundary values -function ColorGradient{T<:Real}(s::Symbol, vals::AVec{T} = 0:0; kw...) +function ColorGradient(s::Symbol, vals::AVec{T} = 0:0; kw...) where T<:Real haskey(_gradients, s) || error("Invalid gradient symbol. Choose from: ", sort(collect(keys(_gradients)))) cs = _gradients[s] if vals == 0:0 @@ -208,7 +208,7 @@ end # -------------------------------------------------------------- "Wraps a function, taking an index and returning a Colorant" -immutable ColorFunction <: ColorScheme +struct ColorFunction <: ColorScheme f::Function end @@ -217,7 +217,7 @@ getColor(scheme::ColorFunction, idx::Int) = scheme.f(idx) # -------------------------------------------------------------- "Wraps a function, taking an z-value and returning a Colorant" -immutable ColorZFunction <: ColorScheme +struct ColorZFunction <: ColorScheme f::Function end @@ -226,7 +226,7 @@ getColorZ(scheme::ColorZFunction, z::Real) = scheme.f(z) # -------------------------------------------------------------- "Wraps a vector of colors... may be vector of Symbol/String/Colorant" -immutable ColorVector <: ColorScheme +struct ColorVector <: ColorScheme v::Vector{Colorant} ColorVector(v::AVec; alpha = nothing) = new(convertColor(v,alpha)) end @@ -238,7 +238,7 @@ getColorVector(scheme::ColorVector) = scheme.v # -------------------------------------------------------------- "Wraps a single color" -immutable ColorWrapper <: ColorScheme +struct ColorWrapper <: ColorScheme c::RGBA ColorWrapper(c::Colorant; alpha = nothing) = new(convertColor(c, alpha)) end @@ -347,8 +347,8 @@ function get_color_palette(palette, bgcolor::Union{Colorant,ColorWrapper}, numco RGBA[getColorZ(grad, z) for z in zrng] end -function get_color_palette{C<:Colorant}(palette::Vector{C}, - bgcolor::Union{Colorant,ColorWrapper}, numcolors::Integer) +function get_color_palette(palette::Vector{C}, +bgcolor::Union{Colorant,ColorWrapper}, numcolors::Integer) where C<:Colorant palette end diff --git a/src/deprecated/series_args.jl b/src/deprecated/series_args.jl index 2d7536f4..b5b02594 100644 --- a/src/deprecated/series_args.jl +++ b/src/deprecated/series_args.jl @@ -5,21 +5,21 @@ # This should cut down on boilerplate code and allow more focused dispatch on type # note: returns meta information... mainly for use with automatic labeling from DataFrames for now -const FuncOrFuncs = @compat(Union{Function, AVec{Function}}) +const FuncOrFuncs = Union{Function, AVec{Function}} all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) # missing -convertToAnyVector(v::@compat(Void), d::KW) = Any[nothing], nothing +convertToAnyVector(v::Void, d::KW) = Any[nothing], nothing # fixed number of blank series convertToAnyVector(n::Integer, d::KW) = Any[zeros(0) for i in 1:n], nothing # numeric vector -convertToAnyVector{T<:Number}(v::AVec{T}, d::KW) = Any[v], nothing +convertToAnyVector(v::AVec{T}, d::KW) where {T<:Number} = Any[v], nothing # string vector -convertToAnyVector{T<:@compat(AbstractString)}(v::AVec{T}, d::KW) = Any[v], nothing +convertToAnyVector(v::AVec{T}, d::KW) where {T<:AbstractString} = Any[v], nothing function convertToAnyVector(v::AMat, d::KW) if all3D(d) @@ -39,7 +39,7 @@ convertToAnyVector(s::Surface, d::KW) = Any[s], nothing # convertToAnyVector(v::AVec{OHLC}, d::KW) = Any[v], nothing # dates -convertToAnyVector{D<:Union{Date,DateTime}}(dts::AVec{D}, d::KW) = Any[dts], nothing +convertToAnyVector(dts::AVec{D}, d::KW) where {D<:Union{Date,DateTime}} = Any[dts], nothing # list of things (maybe other vectors, functions, or something else) function convertToAnyVector(v::AVec, d::KW) diff --git a/src/examples.jl b/src/examples.jl index ed62e00e..3f8acaa3 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -1,7 +1,7 @@ """ Holds all data needed for a documentation example... header, description, and plotting expression (Expr) """ -type PlotExample +mutable struct PlotExample header::AbstractString desc::AbstractString exprs::Vector{Expr} diff --git a/src/layouts.jl b/src/layouts.jl index 9bd4d3b2..63924374 100644 --- a/src/layouts.jl +++ b/src/layouts.jl @@ -13,7 +13,7 @@ Base.zero(::Type{typeof(mm)}) = 0mm Base.one(::Type{typeof(mm)}) = 1mm Base.typemin(::typeof(mm)) = -Inf*mm Base.typemax(::typeof(mm)) = Inf*mm -Base.convert{F<:AbstractFloat}(::Type{F}, l::AbsoluteLength) = convert(F, l.value) +Base.convert(::Type{F}, l::AbsoluteLength) where {F<:AbstractFloat} = convert(F, l.value) # TODO: these are unintuitive and may cause tricky bugs # Base.:+(m1::AbsoluteLength, m2::Length{:pct}) = AbsoluteLength(m1.value * (1 + m2.value)) @@ -95,7 +95,7 @@ end # ----------------------------------------------------------- # points combined by x/y, pct, and length -type MixedMeasures +mutable struct MixedMeasures xy::Float64 pct::Float64 len::AbsoluteLength @@ -216,7 +216,7 @@ bottompad(layout::AbstractLayout) = 0mm # RootLayout # this is the parent of the top-level layout -immutable RootLayout <: AbstractLayout end +struct RootLayout <: AbstractLayout end Base.parent(::RootLayout) = nothing parent_bbox(::RootLayout) = defaultbox @@ -226,7 +226,7 @@ bbox(::RootLayout) = defaultbox # EmptyLayout # contains blank space -type EmptyLayout <: AbstractLayout +mutable struct EmptyLayout <: AbstractLayout parent::AbstractLayout bbox::BoundingBox attr::KW # store label, width, and height for initialization @@ -244,7 +244,7 @@ _update_min_padding!(layout::EmptyLayout) = nothing # GridLayout # nested, gridded layout with optional size percentages -type GridLayout <: AbstractLayout +mutable struct GridLayout <: AbstractLayout parent::AbstractLayout minpad::Tuple # leftpad, toppad, rightpad, bottompad bbox::BoundingBox @@ -481,12 +481,12 @@ function layout_args(n::Integer) GridLayout(nr, nc), n end -function layout_args{I<:Integer}(sztup::NTuple{2,I}) +function layout_args(sztup::NTuple{2,I}) where I<:Integer nr, nc = sztup GridLayout(nr, nc), nr*nc end -function layout_args{I<:Integer}(sztup::NTuple{3,I}) +function layout_args(sztup::NTuple{3,I}) where I<:Integer n, nr, nc = sztup nr, nc = compute_gridsize(n, nr, nc) GridLayout(nr, nc), n diff --git a/src/output.jl b/src/output.jl index f26b6720..37849d8b 100644 --- a/src/output.jl +++ b/src/output.jl @@ -193,7 +193,7 @@ function Base.show(io::IO, ::MIME"text/html", plt::Plot) end end -function _show{B}(io::IO, m, plt::Plot{B}) +function _show(io::IO, m, plt::Plot{B}) where B # Base.show_backtrace(STDOUT, backtrace()) warn("_show is not defined for this backend. m=", string(m)) end @@ -203,7 +203,7 @@ end # for writing to io streams... first prepare, then callback for mime in keys(_mimeformats) - @eval function Base.show{B}(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) + @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) where B prepare_output(plt) _show(io, m, plt) end @@ -293,7 +293,7 @@ end Media.media(Plot, Media.Plot) - _show{B}(io::IO, m::MIME"text/plain", plt::Plot{B}) = print(io, "Plot{$B}()") + _show(io::IO, m::MIME"text/plain", plt::Plot{B}) where {B} = print(io, "Plot{$B}()") function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) diff --git a/src/pipeline.jl b/src/pipeline.jl index a0f17ba4..e8607337 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -301,7 +301,7 @@ end # getting ready to add the series... last update to subplot from anything # that might have been added during series recipes -function _prepare_subplot{T}(plt::Plot{T}, d::KW) +function _prepare_subplot(plt::Plot{T}, d::KW) where T st::Symbol = d[:seriestype] sp::Subplot{T} = d[:subplot] sp_idx = get_subplot_index(plt, sp) diff --git a/src/plot.jl b/src/plot.jl index 8968df8c..38034bec 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -1,5 +1,5 @@ -type CurrentPlot +mutable struct CurrentPlot nullableplot::Nullable{AbstractPlot} end const CURRENT_PLOT = CurrentPlot(Nullable{AbstractPlot}()) diff --git a/src/recipes.jl b/src/recipes.jl index 5501351a..6e49fb03 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -47,7 +47,7 @@ end num_series(x::AMat) = size(x,2) num_series(x) = 1 -RecipesBase.apply_recipe{T}(d::KW, ::Type{T}, plt::AbstractPlot) = throw(MethodError("Unmatched plot recipe: $T")) +RecipesBase.apply_recipe(d::KW, ::Type{T}, plt::AbstractPlot) where {T} = throw(MethodError("Unmatched plot recipe: $T")) # --------------------------------------------------------------------------- @@ -343,9 +343,9 @@ _bin_centers(v::AVec) = (v[1:end-1] + v[2:end]) / 2 _is_positive(x) = (x > 0) && !(x ≈ 0) -_positive_else_nan{T}(::Type{T}, x::Real) = _is_positive(x) ? T(x) : T(NaN) +_positive_else_nan(::Type{T}, x::Real) where {T} = _is_positive(x) ? T(x) : T(NaN) -function _scale_adjusted_values{T<:AbstractFloat}(::Type{T}, V::AbstractVector, scale::Symbol) +function _scale_adjusted_values(::Type{T}, V::AbstractVector, scale::Symbol) where T<:AbstractFloat if scale in _logScales [_positive_else_nan(T, x) for x in V] else @@ -354,7 +354,7 @@ function _scale_adjusted_values{T<:AbstractFloat}(::Type{T}, V::AbstractVector, end -function _binbarlike_baseline{T<:Real}(min_value::T, scale::Symbol) +function _binbarlike_baseline(min_value::T, scale::Symbol) where T<:Real if (scale in _logScales) !isnan(min_value) ? min_value / T(_logScaleBases[scale]^log10(2)) : T(1E-3) else @@ -363,7 +363,7 @@ function _binbarlike_baseline{T<:Real}(min_value::T, scale::Symbol) end -function _preprocess_binbarlike_weights{T<:AbstractFloat}(::Type{T}, w, wscale::Symbol) +function _preprocess_binbarlike_weights(::Type{T}, w, wscale::Symbol) where T<:AbstractFloat w_adj = _scale_adjusted_values(T, w, wscale) w_min = ignorenan_minimum(w_adj) w_max = ignorenan_maximum(w_adj) @@ -499,7 +499,7 @@ Plots.@deps stepbins path wand_edges(x...) = (warn("Load the StatPlots package in order to use :wand bins. Defaulting to :auto", once = true); :auto) -function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) +function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::Symbol = :auto) where N _cl(x) = ceil(Int, NaNMath.max(x, one(x))) _iqr(v) = (q = quantile(v, 0.75) - quantile(v, 0.25); q > 0 ? q : oftype(q, 1)) _span(v) = ignorenan_maximum(v) - ignorenan_minimum(v) @@ -533,20 +533,20 @@ function _auto_binning_nbins{N}(vs::NTuple{N,AbstractVector}, dim::Integer; mode end end -_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) = StatsBase.histrange(vs[dim], binning, :left) -_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) -_hist_edge{N}(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) = binning +_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Integer) where {N} = StatsBase.histrange(vs[dim], binning, :left) +_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::Symbol) where {N} = _hist_edge(vs, dim, _auto_binning_nbins(vs, dim, mode = binning)) +_hist_edge(vs::NTuple{N,AbstractVector}, dim::Integer, binning::AbstractVector) where {N} = binning -_hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) = +_hist_edges(vs::NTuple{N,AbstractVector}, binning::NTuple{N}) where {N} = map(dim -> _hist_edge(vs, dim, binning[dim]), (1:N...)) -_hist_edges{N}(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) = +_hist_edges(vs::NTuple{N,AbstractVector}, binning::Union{Integer, Symbol, AbstractVector}) where {N} = map(dim -> _hist_edge(vs, dim, binning), (1:N...)) _hist_norm_mode(mode::Symbol) = mode _hist_norm_mode(mode::Bool) = mode ? :pdf : :none -function _make_hist{N}(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) +function _make_hist(vs::NTuple{N,AbstractVector}, binning; normed = false, weights = nothing) where N edges = _hist_edges(vs, binning) h = float( weights == nothing ? StatsBase.fit(StatsBase.Histogram, vs, edges, closed = :left) : @@ -590,7 +590,7 @@ end @deps scatterhist scatterbins -@recipe function f{T, E}(h::StatsBase.Histogram{T, 1, E}) +@recipe function f(h::StatsBase.Histogram{T, 1, E}) where {T, E} seriestype --> :barbins st_map = Dict( @@ -611,7 +611,7 @@ end end -@recipe function f{H <: StatsBase.Histogram}(hv::AbstractVector{H}) +@recipe function f(hv::AbstractVector{H}) where H <: StatsBase.Histogram for h in hv @series begin h @@ -658,7 +658,7 @@ end @deps histogram2d bins2d -@recipe function f{T, E}(h::StatsBase.Histogram{T, 2, E}) +@recipe function f(h::StatsBase.Histogram{T, 2, E}) where {T, E} seriestype --> :bins2d (h.edges[1], h.edges[2], Surface(h.weights)) end @@ -855,7 +855,7 @@ end # TODO: move OHLC to PlotRecipes finance.jl "Represent Open High Low Close data (used in finance)" -type OHLC{T<:Real} +mutable struct OHLC{T<:Real} open::T high::T low::T @@ -894,10 +894,10 @@ end # to squash ambiguity warnings... @recipe f(x::AVec{Function}, v::AVec{OHLC}) = error() -@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(x::AVec{Function}, v::AVec{Tuple{R1,R2,R3,R4}}) = error() +@recipe f(x::AVec{Function}, v::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = error() # this must be OHLC? -@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(x::AVec, ohlc::AVec{Tuple{R1,R2,R3,R4}}) = x, OHLC[OHLC(t...) for t in ohlc] +@recipe f(x::AVec, ohlc::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = x, OHLC[OHLC(t...) for t in ohlc] @recipe function f(x::AVec, v::AVec{OHLC}) seriestype := :path @@ -987,7 +987,7 @@ datetimeformatter(dt) = string(DateTime(Dates.UTM(dt))) # ------------------------------------------------- # Complex Numbers -@recipe function f{T<:Number}(A::Array{Complex{T}}) +@recipe function f(A::Array{Complex{T}}) where T<:Number xguide --> "Re(x)" yguide --> "Im(x)" real.(A), imag.(A) @@ -996,7 +996,7 @@ end # Splits a complex matrix to its real and complex parts # Reals defaults solid, imaginary defaults dashed # Label defaults are changed to match the real-imaginary reference / indexing -@recipe function f{T<:Real,T2}(x::AbstractArray{T},y::Array{Complex{T2}}) +@recipe function f(x::AbstractArray{T},y::Array{Complex{T2}}) where {T<:Real,T2} ylabel --> "Re(y)" zlabel --> "Im(y)" x,real.(y),imag.(y) diff --git a/src/series.jl b/src/series.jl index c0d7d4c2..1f00bb6e 100644 --- a/src/series.jl +++ b/src/series.jl @@ -20,10 +20,10 @@ convertToAnyVector(v::Void, d::KW) = Any[nothing], nothing convertToAnyVector(n::Integer, d::KW) = Any[zeros(0) for i in 1:n], nothing # numeric vector -convertToAnyVector{T<:Number}(v::AVec{T}, d::KW) = Any[v], nothing +convertToAnyVector(v::AVec{T}, d::KW) where {T<:Number} = Any[v], nothing # string vector -convertToAnyVector{T<:AbstractString}(v::AVec{T}, d::KW) = Any[v], nothing +convertToAnyVector(v::AVec{T}, d::KW) where {T<:AbstractString} = Any[v], nothing function convertToAnyVector(v::AMat, d::KW) if all3D(d) @@ -99,8 +99,8 @@ nobigs(v) = v end # not allowed -compute_xyz{F<:Function}(x::Void, y::FuncOrFuncs{F}, z) = error("If you want to plot the function `$y`, you need to define the x values!") -compute_xyz{F<:Function}(x::Void, y::Void, z::FuncOrFuncs{F}) = error("If you want to plot the function `$z`, you need to define x and y values!") +compute_xyz(x::Void, y::FuncOrFuncs{F}, z) where {F<:Function} = error("If you want to plot the function `$y`, you need to define the x values!") +compute_xyz(x::Void, y::Void, z::FuncOrFuncs{F}) where {F<:Function} = error("If you want to plot the function `$z`, you need to define x and y values!") compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!") # -------------------------------------------------------------------- @@ -109,7 +109,7 @@ compute_xyz(x::Void, y::Void, z::Void) = error("x/y/z are all nothing!") # we are going to build recipes to do the processing and splitting of the args # ensure we dispatch to the slicer -immutable SliceIt end +struct SliceIt end # the catch-all recipes @recipe function f(::Type{SliceIt}, x, y, z) @@ -163,10 +163,10 @@ immutable SliceIt end end # this is the default "type recipe"... just pass the object through -@recipe f{T<:Any}(::Type{T}, v::T) = v +@recipe f(::Type{T}, v::T) where {T<:Any} = v # this should catch unhandled "series recipes" and error with a nice message -@recipe f{V<:Val}(::Type{V}, x, y, z) = error("The backend must not support the series type $V, and there isn't a series recipe defined.") +@recipe f(::Type{V}, x, y, z) where {V<:Val} = error("The backend must not support the series type $V, and there isn't a series recipe defined.") _apply_type_recipe(d, v) = RecipesBase.apply_recipe(d, typeof(v), v)[1].args[1] @@ -201,7 +201,7 @@ end # end # don't do anything for ints or floats -_apply_type_recipe{T<:Union{Integer,AbstractFloat}}(d, v::AbstractArray{T}) = v +_apply_type_recipe(d, v::AbstractArray{T}) where {T<:Union{Integer,AbstractFloat}} = v # handle "type recipes" by converting inputs, and then either re-calling or slicing @recipe function f(x, y, z) @@ -274,7 +274,7 @@ end @recipe f(n::Integer) = is3d(get(plotattributes,: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}) +@recipe function f(mat::AMat{T}) where T<:Union{Integer,AbstractFloat} if all3D(plotattributes) n,m = size(mat) wrap_surfaces(plotattributes) @@ -285,7 +285,7 @@ end end # if a matrix is wrapped by Formatted, do similar logic, but wrap data with Surface -@recipe function f{T<:AbstractMatrix}(fmt::Formatted{T}) +@recipe function f(fmt::Formatted{T}) where T<:AbstractMatrix if all3D(plotattributes) mat = fmt.data n,m = size(mat) @@ -297,7 +297,7 @@ end end # assume this is a Volume, so construct one -@recipe function f{T<:Number}(vol::AbstractArray{T,3}, args...) +@recipe function f(vol::AbstractArray{T,3}, args...) where T<:Number seriestype := :volume SliceIt, nothing, Volume(vol, args...), nothing end @@ -305,7 +305,7 @@ end # # images - grays -@recipe function f{T<:Gray}(mat::AMat{T}) +@recipe function f(mat::AMat{T}) where T<:Gray if is_seriestype_supported(:image) seriestype := :image n, m = size(mat) @@ -320,7 +320,7 @@ end # # images - colors -@recipe function f{T<:Colorant}(mat::AMat{T}) +@recipe function f(mat::AMat{T}) where T<:Colorant n, m = size(mat) if is_seriestype_supported(:image) @@ -358,7 +358,7 @@ end # function without range... use the current range of the x-axis -@recipe function f{F<:Function}(f::FuncOrFuncs{F}) +@recipe function f(f::FuncOrFuncs{F}) where F<:Function plt = plotattributes[:plot_object] xmin, xmax = try axis_limits(plt[1][:xaxis]) @@ -397,7 +397,7 @@ end # # if functions come first, just swap the order (not to be confused with parametric functions... # # as there would be more than one function passed in) -@recipe function f{F<:Function}(f::FuncOrFuncs{F}, x) +@recipe function f(f::FuncOrFuncs{F}, x) where F<:Function F2 = typeof(x) @assert !(F2 <: Function || (F2 <: AbstractArray && F2.parameters[1] <: Function)) # otherwise we'd hit infinite recursion here x, f @@ -465,19 +465,19 @@ end xs = adapted_grid(f, (xmin, xmax)) xs, f end -@recipe function f{F<:Function}(fs::AbstractArray{F}, xmin::Number, xmax::Number) +@recipe function f(fs::AbstractArray{F}, xmin::Number, xmax::Number) where F<:Function xs = Any[adapted_grid(f, (xmin, xmax)) for f in fs] xs, fs end -@recipe f{F<:Function,G<:Function}(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, u::AVec) = mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u) -@recipe f{F<:Function,G<:Function}(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) = fx, fy, linspace(umin, umax, n) +@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, u::AVec) where {F<:Function,G<:Function} = mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u) +@recipe f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, umin::Number, umax::Number, n = 200) where {F<:Function,G<:Function} = fx, fy, linspace(umin, umax, n) # # # special handling... 3D parametric function(s) -@recipe function f{F<:Function,G<:Function,H<:Function}(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, u::AVec) +@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, u::AVec) where {F<:Function,G<:Function,H<:Function} mapFuncOrFuncs(fx, u), mapFuncOrFuncs(fy, u), mapFuncOrFuncs(fz, u) end -@recipe function f{F<:Function,G<:Function,H<:Function}(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, umin::Number, umax::Number, numPoints = 200) +@recipe function f(fx::FuncOrFuncs{F}, fy::FuncOrFuncs{G}, fz::FuncOrFuncs{H}, umin::Number, umax::Number, numPoints = 200) where {F<:Function,G<:Function,H<:Function} fx, fy, fz, linspace(umin, umax, numPoints) end @@ -492,28 +492,28 @@ end # # # (x,y) tuples -@recipe f{R1<:Number,R2<:Number}(xy::AVec{Tuple{R1,R2}}) = unzip(xy) -@recipe f{R1<:Number,R2<:Number}(xy::Tuple{R1,R2}) = [xy[1]], [xy[2]] +@recipe f(xy::AVec{Tuple{R1,R2}}) where {R1<:Number,R2<:Number} = unzip(xy) +@recipe f(xy::Tuple{R1,R2}) where {R1<:Number,R2<:Number} = [xy[1]], [xy[2]] # # # (x,y,z) tuples -@recipe f{R1<:Number,R2<:Number,R3<:Number}(xyz::AVec{Tuple{R1,R2,R3}}) = unzip(xyz) -@recipe f{R1<:Number,R2<:Number,R3<:Number}(xyz::Tuple{R1,R2,R3}) = [xyz[1]], [xyz[2]], [xyz[3]] +@recipe f(xyz::AVec{Tuple{R1,R2,R3}}) where {R1<:Number,R2<:Number,R3<:Number} = unzip(xyz) +@recipe f(xyz::Tuple{R1,R2,R3}) where {R1<:Number,R2<:Number,R3<:Number} = [xyz[1]], [xyz[2]], [xyz[3]] # these might be points+velocity, or OHLC or something else -@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::AVec{Tuple{R1,R2,R3,R4}}) = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) -@recipe f{R1<:Number,R2<:Number,R3<:Number,R4<:Number}(xyuv::Tuple{R1,R2,R3,R4}) = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]] +@recipe f(xyuv::AVec{Tuple{R1,R2,R3,R4}}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = get(plotattributes,:seriestype,:path)==:ohlc ? OHLC[OHLC(t...) for t in xyuv] : unzip(xyuv) +@recipe f(xyuv::Tuple{R1,R2,R3,R4}) where {R1<:Number,R2<:Number,R3<:Number,R4<:Number} = [xyuv[1]], [xyuv[2]], [xyuv[3]], [xyuv[4]] # # # 2D FixedSizeArrays -@recipe f{T<:Number}(xy::AVec{FixedSizeArrays.Vec{2,T}}) = unzip(xy) -@recipe f{T<:Number}(xy::FixedSizeArrays.Vec{2,T}) = [xy[1]], [xy[2]] +@recipe f(xy::AVec{FixedSizeArrays.Vec{2,T}}) where {T<:Number} = unzip(xy) +@recipe f(xy::FixedSizeArrays.Vec{2,T}) where {T<:Number} = [xy[1]], [xy[2]] # # # 3D FixedSizeArrays -@recipe f{T<:Number}(xyz::AVec{FixedSizeArrays.Vec{3,T}}) = unzip(xyz) -@recipe f{T<:Number}(xyz::FixedSizeArrays.Vec{3,T}) = [xyz[1]], [xyz[2]], [xyz[3]] +@recipe f(xyz::AVec{FixedSizeArrays.Vec{3,T}}) where {T<:Number} = unzip(xyz) +@recipe f(xyz::FixedSizeArrays.Vec{3,T}) where {T<:Number} = [xyz[1]], [xyz[2]], [xyz[3]] # # # -------------------------------------------------------------------- diff --git a/src/subplots.jl b/src/subplots.jl index 5629125f..a47bc8ee 100644 --- a/src/subplots.jl +++ b/src/subplots.jl @@ -1,6 +1,6 @@ -function Subplot{T<:AbstractBackend}(::T; parent = RootLayout()) +function Subplot(::T; parent = RootLayout()) where T<:AbstractBackend Subplot{T}( parent, Series[], diff --git a/src/types.jl b/src/types.jl index 3e07587b..bd53715b 100644 --- a/src/types.jl +++ b/src/types.jl @@ -6,20 +6,20 @@ const AVec = AbstractVector const AMat = AbstractMatrix const KW = Dict{Symbol,Any} -immutable PlotsDisplay <: Display end +struct PlotsDisplay <: Display end # ----------------------------------------------------------- -immutable InputWrapper{T} +struct InputWrapper{T} obj::T end -wrap{T}(obj::T) = InputWrapper{T}(obj) +wrap(obj::T) where {T} = InputWrapper{T}(obj) Base.isempty(wrapper::InputWrapper) = false # ----------------------------------------------------------- -type Series +mutable struct Series d::KW end @@ -29,7 +29,7 @@ attr!(series::Series, v, k::Symbol) = (series.d[k] = v) # ----------------------------------------------------------- # a single subplot -type Subplot{T<:AbstractBackend} <: AbstractLayout +mutable struct Subplot{T<:AbstractBackend} <: AbstractLayout parent::AbstractLayout series_list::Vector{Series} # arguments for each series minpad::Tuple # leftpad, toppad, rightpad, bottompad @@ -45,12 +45,12 @@ Base.show(io::IO, sp::Subplot) = print(io, "Subplot{$(sp[:subplot_index])}") # ----------------------------------------------------------- # simple wrapper around a KW so we can hold all attributes pertaining to the axis in one place -type Axis +mutable struct Axis sps::Vector{Subplot} d::KW end -type Extrema +mutable struct Extrema emin::Float64 emax::Float64 end @@ -63,7 +63,7 @@ const SubplotMap = Dict{Any, Subplot} # ----------------------------------------------------------- -type Plot{T<:AbstractBackend} <: AbstractPlot{T} +mutable struct Plot{T<:AbstractBackend} <: AbstractPlot{T} backend::T # the backend type n::Int # number of series attr::KW # arguments for the whole plot diff --git a/src/utils.jl b/src/utils.jl index 65142bfc..81cd3571 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -114,7 +114,7 @@ function regressionXY(x, y) regx, regy end -function replace_image_with_heatmap{T<:Colorant}(z::Array{T}) +function replace_image_with_heatmap(z::Array{T}) where T<:Colorant @show T, size(z) n, m = size(z) # idx = 0 @@ -138,14 +138,14 @@ end # --------------------------------------------------------------- "Build line segments for plotting" -type Segments{T} +mutable struct Segments{T} pts::Vector{T} end # Segments() = Segments{Float64}(zeros(0)) Segments() = Segments(Float64) -Segments{T}(::Type{T}) = Segments(T[]) +Segments(::Type{T}) where {T} = Segments(T[]) Segments(p::Int) = Segments(NTuple{2,Float64}[]) @@ -157,7 +157,7 @@ to_nan(::Type{NTuple{2,Float64}}) = (NaN, NaN) coords(segs::Segments{Float64}) = segs.pts coords(segs::Segments{NTuple{2,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts] -function Base.push!{T}(segments::Segments{T}, vs...) +function Base.push!(segments::Segments{T}, vs...) where T if !isempty(segments.pts) push!(segments.pts, to_nan(T)) end @@ -167,7 +167,7 @@ function Base.push!{T}(segments::Segments{T}, vs...) segments end -function Base.push!{T}(segments::Segments{T}, vs::AVec) +function Base.push!(segments::Segments{T}, vs::AVec) where T if !isempty(segments.pts) push!(segments.pts, to_nan(T)) end @@ -181,7 +181,7 @@ end # ----------------------------------------------------- # helper to manage NaN-separated segments -type SegmentsIterator +mutable struct SegmentsIterator args::Tuple n::Int end @@ -232,8 +232,8 @@ end # Find minimal type that can contain NaN and x # To allow use of NaN separated segments with categorical x axis -float_extended_type{T}(x::AbstractArray{T}) = Union{T,Float64} -float_extended_type{T<:Real}(x::AbstractArray{T}) = Float64 +float_extended_type(x::AbstractArray{T}) where {T} = Union{T,Float64} +float_extended_type(x::AbstractArray{T}) where {T<:Real} = Float64 # ------------------------------------------------------------------------------------ @@ -259,27 +259,27 @@ _cycle(grad::ColorGradient, idx::Int) = _cycle(grad.colors, idx) _cycle(grad::ColorGradient, indices::AVec{Int}) = _cycle(grad.colors, indices) makevec(v::AVec) = v -makevec{T}(v::T) = T[v] +makevec(v::T) where {T} = T[v] "duplicate a single value, or pass the 2-tuple through" maketuple(x::Real) = (x,x) -maketuple{T,S}(x::Tuple{T,S}) = x +maketuple(x::Tuple{T,S}) where {T,S} = x mapFuncOrFuncs(f::Function, u::AVec) = map(f, u) -mapFuncOrFuncs{F<:Function}(fs::AVec{F}, u::AVec) = [map(f, u) for f in fs] +mapFuncOrFuncs(fs::AVec{F}, u::AVec) where {F<:Function} = [map(f, u) for f in fs] -unzip{X,Y}(xy::AVec{Tuple{X,Y}}) = [t[1] for t in xy], [t[2] for t in xy] -unzip{X,Y,Z}(xyz::AVec{Tuple{X,Y,Z}}) = [t[1] for t in xyz], [t[2] for t in xyz], [t[3] for t in xyz] -unzip{X,Y,U,V}(xyuv::AVec{Tuple{X,Y,U,V}}) = [t[1] for t in xyuv], [t[2] for t in xyuv], [t[3] for t in xyuv], [t[4] for t in xyuv] +unzip(xy::AVec{Tuple{X,Y}}) where {X,Y} = [t[1] for t in xy], [t[2] for t in xy] +unzip(xyz::AVec{Tuple{X,Y,Z}}) where {X,Y,Z} = [t[1] for t in xyz], [t[2] for t in xyz], [t[3] for t in xyz] +unzip(xyuv::AVec{Tuple{X,Y,U,V}}) where {X,Y,U,V} = [t[1] for t in xyuv], [t[2] for t in xyuv], [t[3] for t in xyuv], [t[4] for t in xyuv] -unzip{T}(xy::AVec{FixedSizeArrays.Vec{2,T}}) = T[t[1] for t in xy], T[t[2] for t in xy] -unzip{T}(xy::FixedSizeArrays.Vec{2,T}) = T[xy[1]], T[xy[2]] +unzip(xy::AVec{FixedSizeArrays.Vec{2,T}}) where {T} = T[t[1] for t in xy], T[t[2] for t in xy] +unzip(xy::FixedSizeArrays.Vec{2,T}) where {T} = T[xy[1]], T[xy[2]] -unzip{T}(xyz::AVec{FixedSizeArrays.Vec{3,T}}) = T[t[1] for t in xyz], T[t[2] for t in xyz], T[t[3] for t in xyz] -unzip{T}(xyz::FixedSizeArrays.Vec{3,T}) = T[xyz[1]], T[xyz[2]], T[xyz[3]] +unzip(xyz::AVec{FixedSizeArrays.Vec{3,T}}) where {T} = T[t[1] for t in xyz], T[t[2] for t in xyz], T[t[3] for t in xyz] +unzip(xyz::FixedSizeArrays.Vec{3,T}) where {T} = T[xyz[1]], T[xyz[2]], T[xyz[3]] -unzip{T}(xyuv::AVec{FixedSizeArrays.Vec{4,T}}) = T[t[1] for t in xyuv], T[t[2] for t in xyuv], T[t[3] for t in xyuv], T[t[4] for t in xyuv] -unzip{T}(xyuv::FixedSizeArrays.Vec{4,T}) = T[xyuv[1]], T[xyuv[2]], T[xyuv[3]], T[xyuv[4]] +unzip(xyuv::AVec{FixedSizeArrays.Vec{4,T}}) where {T} = T[t[1] for t in xyuv], T[t[2] for t in xyuv], T[t[3] for t in xyuv], T[t[4] for t in xyuv] +unzip(xyuv::FixedSizeArrays.Vec{4,T}) where {T} = T[xyuv[1]], T[xyuv[2]], T[xyuv[3]], T[xyuv[4]] # given 2-element lims and a vector of data x, widen lims to account for the extrema of x function _expand_limits(lims, x) @@ -388,7 +388,7 @@ isatom() = isdefined(Main, :Atom) && Main.Atom.isconnected() function is_installed(pkgstr::AbstractString) try - Pkg.installed(pkgstr) === nothing ? false: true + Pkg.installed(pkgstr) === nothing ? false : true catch false end @@ -410,20 +410,20 @@ isvertical(d::KW) = get(d, :orientation, :vertical) in (:vertical, :v, :vert) isvertical(series::Series) = isvertical(series.d) -ticksType{T<:Real}(ticks::AVec{T}) = :ticks -ticksType{T<:AbstractString}(ticks::AVec{T}) = :labels -ticksType{T<:AVec,S<:AVec}(ticks::Tuple{T,S}) = :ticks_and_labels +ticksType(ticks::AVec{T}) where {T<:Real} = :ticks +ticksType(ticks::AVec{T}) where {T<:AbstractString} = :labels +ticksType(ticks::Tuple{T,S}) where {T<:AVec,S<:AVec} = :ticks_and_labels ticksType(ticks) = :invalid -limsType{T<:Real,S<:Real}(lims::Tuple{T,S}) = :limits +limsType(lims::Tuple{T,S}) where {T<:Real,S<:Real} = :limits limsType(lims::Symbol) = lims == :auto ? :auto : :invalid limsType(lims) = :invalid # axis_Symbol(letter, postfix) = Symbol(letter * postfix) # axis_symbols(letter, postfix...) = map(s -> axis_Symbol(letter, s), postfix) -Base.convert{T<:Real}(::Type{Vector{T}}, rng::Range{T}) = T[x for x in rng] -Base.convert{T<:Real,S<:Real}(::Type{Vector{T}}, rng::Range{S}) = T[x for x in rng] +Base.convert(::Type{Vector{T}}, rng::Range{T}) where {T<:Real} = T[x for x in rng] +Base.convert(::Type{Vector{T}}, rng::Range{S}) where {T<:Real,S<:Real} = T[x for x in rng] Base.merge(a::AbstractVector, b::AbstractVector) = sort(unique(vcat(a,b))) @@ -727,7 +727,7 @@ end # --------------------------------------------------------------- # --------------------------------------------------------------- -type DebugMode +mutable struct DebugMode on::Bool end const _debugMode = DebugMode(false) @@ -765,10 +765,10 @@ end extendSeriesByOne(v::UnitRange{Int}, n::Int = 1) = isempty(v) ? (1:n) : (minimum(v):maximum(v)+n) extendSeriesByOne(v::AVec, n::Integer = 1) = isempty(v) ? (1:n) : vcat(v, (1:n) + ignorenan_maximum(v)) -extendSeriesData{T}(v::Range{T}, z::Real) = extendSeriesData(float(collect(v)), z) -extendSeriesData{T}(v::Range{T}, z::AVec) = extendSeriesData(float(collect(v)), z) -extendSeriesData{T}(v::AVec{T}, z::Real) = (push!(v, convert(T, z)); v) -extendSeriesData{T}(v::AVec{T}, z::AVec) = (append!(v, convert(Vector{T}, z)); v) +extendSeriesData(v::Range{T}, z::Real) where {T} = extendSeriesData(float(collect(v)), z) +extendSeriesData(v::Range{T}, z::AVec) where {T} = extendSeriesData(float(collect(v)), z) +extendSeriesData(v::AVec{T}, z::Real) where {T} = (push!(v, convert(T, z)); v) +extendSeriesData(v::AVec{T}, z::AVec) where {T} = (append!(v, convert(Vector{T}, z)); v) # ------------------------------------------------------- @@ -786,14 +786,14 @@ function getxyz(plt::Plot, i::Integer) tovec(d[:x]), tovec(d[:y]), tovec(d[:z]) end -function setxy!{X,Y}(plt::Plot, xy::Tuple{X,Y}, i::Integer) +function setxy!(plt::Plot, xy::Tuple{X,Y}, i::Integer) where {X,Y} series = plt.series_list[i] series.d[:x], series.d[:y] = xy sp = series.d[:subplot] reset_extrema!(sp) _series_updated(plt, series) end -function setxyz!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) +function setxyz!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z} series = plt.series_list[i] series.d[:x], series.d[:y], series.d[:z] = xyz sp = series.d[:subplot] @@ -801,7 +801,7 @@ function setxyz!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) _series_updated(plt, series) end -function setxyz!{X,Y,Z<:AbstractMatrix}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) +function setxyz!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z<:AbstractMatrix} setxyz!(plt, (xyz[1], xyz[2], Surface(xyz[3])), i) end @@ -810,8 +810,8 @@ end # indexing notation # Base.getindex(plt::Plot, i::Integer) = getxy(plt, i) -Base.setindex!{X,Y}(plt::Plot, xy::Tuple{X,Y}, i::Integer) = (setxy!(plt, xy, i); plt) -Base.setindex!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) = (setxyz!(plt, xyz, i); plt) +Base.setindex!(plt::Plot, xy::Tuple{X,Y}, i::Integer) where {X,Y} = (setxy!(plt, xy, i); plt) +Base.setindex!(plt::Plot, xyz::Tuple{X,Y,Z}, i::Integer) where {X,Y,Z} = (setxyz!(plt, xyz, i); plt) # ------------------------------------------------------- @@ -923,10 +923,10 @@ function Base.append!(plt::Plot, i::Integer, x::AVec, y::AVec, z::AVec) end # tuples -Base.push!{X,Y}(plt::Plot, xy::Tuple{X,Y}) = push!(plt, 1, xy...) -Base.push!{X,Y,Z}(plt::Plot, xyz::Tuple{X,Y,Z}) = push!(plt, 1, xyz...) -Base.push!{X,Y}(plt::Plot, i::Integer, xy::Tuple{X,Y}) = push!(plt, i, xy...) -Base.push!{X,Y,Z}(plt::Plot, i::Integer, xyz::Tuple{X,Y,Z}) = push!(plt, i, xyz...) +Base.push!(plt::Plot, xy::Tuple{X,Y}) where {X,Y} = push!(plt, 1, xy...) +Base.push!(plt::Plot, xyz::Tuple{X,Y,Z}) where {X,Y,Z} = push!(plt, 1, xyz...) +Base.push!(plt::Plot, i::Integer, xy::Tuple{X,Y}) where {X,Y} = push!(plt, i, xy...) +Base.push!(plt::Plot, i::Integer, xyz::Tuple{X,Y,Z}) where {X,Y,Z} = push!(plt, i, xyz...) # ------------------------------------------------------- # push/append for all series From c76fc5b9096a700f1d5a3c597ebdd525b754aa72 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Oct 2017 20:47:06 +0200 Subject: [PATCH 437/720] use fg_color for matrices with unique non-zeros in spy recipe --- src/recipes.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 6e49fb03..bae34819 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -937,8 +937,7 @@ end mat = g.args[1] if length(unique(mat[mat .!= 0])) < 2 legend --> nothing - # revert the default gradient to have a darker (almost black) color in the default theme - seriescolor --> cgrad([cgrad()[0], cgrad()[1]]) + seriescolor --> cgrad([invisible(), fg_color(plotattributes)]) end n,m = size(mat) Plots.SliceIt, 1:m, 1:n, Surface(mat) From e78bf87377cbf5cac4f5808f9e964eb0bc77fda0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Oct 2017 20:24:07 +0200 Subject: [PATCH 438/720] update some test_examples --- src/examples.jl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 3f8acaa3..6d1f1589 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -262,7 +262,8 @@ PlotExample("Groups and Subplots", "", [:(begin group = rand(map(i->"group $i",1:4),100) - plot(rand(100), layout=@layout([a b;c]), group=group, linetype=[:bar :scatter :steppre]) + plot(rand(100), layout=@layout([a b;c]), group=group, + linetype=[:bar :scatter :steppre], linewidth = [0 0 1]) end)] ), @@ -322,11 +323,11 @@ PlotExample("Animation with subplots", ), PlotExample("Spy", - "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`.", + "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`.", [:(begin a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) - plot(spy(a, markershape = :dtriangle), spy(b), markersize = 3, title = ["Unique nonzeros" "Different nonzeros"]) + plot(spy(a), spy(b), title = ["Unique nonzeros" "Different nonzeros"]) end)] ), @@ -345,8 +346,10 @@ PlotExample("Magic grid argument", PlotExample("Framestyle", "The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`.", [:(begin - histogram(fill(randn(1000), 5), framestyle = [:box :semi :axes :grid :none], - title = [":box" ":semi" ":axes" ":grid" ":none"], color = RowVector(1:5), layout = 5, label = "") + scatter(fill(randn(10), 7), fill(randn(10), 7), + framestyle = [:box :semi :origin :zerolines :grid :none], + title = [":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], + color = RowVector(1:7), layout = 7, label = "", markerstrokewidth = 0) end)] ), From 6d4f4568261fc8401cde709addaafbe9a64d8c0d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Oct 2017 21:06:37 +0200 Subject: [PATCH 439/720] fix framestyle testexample --- src/examples.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 6d1f1589..3e4868b6 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -346,10 +346,10 @@ PlotExample("Magic grid argument", PlotExample("Framestyle", "The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`.", [:(begin - scatter(fill(randn(10), 7), fill(randn(10), 7), + scatter(fill(randn(10), 6), fill(randn(10), 6), framestyle = [:box :semi :origin :zerolines :grid :none], title = [":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], - color = RowVector(1:7), layout = 7, label = "", markerstrokewidth = 0) + color = RowVector(1:6), layout = 6, label = "", markerstrokewidth = 0) end)] ), From 7ffd1fc9c208fc53dba10d46df941b11a6aa6f98 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Oct 2017 21:24:28 +0200 Subject: [PATCH 440/720] some further improvements for framestyle and group testexamples --- src/examples.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index 3e4868b6..b3ac5f6b 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -263,7 +263,7 @@ PlotExample("Groups and Subplots", [:(begin group = rand(map(i->"group $i",1:4),100) plot(rand(100), layout=@layout([a b;c]), group=group, - linetype=[:bar :scatter :steppre], linewidth = [0 0 1]) + linetype=[:bar :scatter :steppre], linecolor = :match) end)] ), @@ -349,7 +349,8 @@ PlotExample("Framestyle", scatter(fill(randn(10), 6), fill(randn(10), 6), framestyle = [:box :semi :origin :zerolines :grid :none], title = [":box" ":semi" ":origin" ":zerolines" ":grid" ":none"], - color = RowVector(1:6), layout = 6, label = "", markerstrokewidth = 0) + color = RowVector(1:6), layout = 6, label = "", markerstrokewidth = 0, + ticks = -2:2) end)] ), From 0c4750547ab2c4b22838e3a710197067bdaf5ce4 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 19 Oct 2017 15:29:52 +0100 Subject: [PATCH 441/720] Fix LaTeX error for log scale ticks. --- src/backends/pgfplots.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index a5f1a1b0..10eb63de 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -300,7 +300,15 @@ function pgf_axis(sp::Subplot, letter) if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none ticks = get_ticks(axis) push!(style, string(letter, "tick = {", join(ticks[1],","), "}")) - if axis[:showaxis] + if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto + # wrap the power part of label with } + tick_labels = String[begin + base, power = split(label, "^") + power = string("{", power, "}") + string(base, "^", power) + end for label in ticks[2]] + push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}")) + elseif axis[:showaxis] push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) else push!(style, string(letter, "ticklabels = {}")) From cdcbdc308c1a3cec3792986ef2cd8c2680f398c8 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 13 Sep 2017 22:14:59 +0200 Subject: [PATCH 442/720] include backend files --- src/Plots.jl | 2 ++ src/backends/glvisualize.jl | 4 ++++ src/backends/gr.jl | 3 +++ src/backends/hdf5.jl | 5 ++++- src/backends/inspectdr.jl | 4 ++++ src/backends/pgfplots.jl | 4 ++++ src/backends/plotly.jl | 4 ++++ src/backends/plotlyjs.jl | 3 +++ src/backends/pyplot.jl | 3 +++ src/backends/unicodeplots.jl | 4 ++++ src/backends/web.jl | 4 +++- src/output.jl | 1 - 12 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index d4f05cc5..51d70256 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -15,6 +15,8 @@ using Base.Meta import Showoff import StatsBase +using Requires + export grid, bbox, diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 716ce78a..924eca72 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -9,6 +9,10 @@ TODO * fix units in all visuals (e.g dotted lines, marker scale, surfaces) =# +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl")) +end + const _glvisualize_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 791055ed..facfeb7f 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -3,6 +3,9 @@ # significant contributions by @jheinen +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "gr.jl")) +end const _gr_attr = merge_with_base_supported([ :annotations, diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index 3adc912a..3e5afa87 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -28,6 +28,9 @@ Read from .hdf5 file using: - Should be reliable for archival purposes. ==# +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "hdf5.jl")) +end import FixedPointNumbers: N0f8 #In core Julia @@ -128,7 +131,7 @@ function _hdf5_merge!(dest::Dict, src::Dict) _hdf5_merge!(dest[k].d, v.d) else dest[k] = v - end + end end return end diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 65f019a0..da7bc144 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -13,6 +13,10 @@ Add in functionality to Plots.jl: :aspect_ratio, =# +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl")) +end + # --------------------------------------------------------------------------- #TODO: remove features const _inspectdr_attr = merge_with_base_supported([ diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 10eb63de..2ae69b3f 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -2,6 +2,10 @@ # significant contributions by: @pkofod +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pgfplots.jl")) +end + const _pgfplots_attr = merge_with_base_supported([ :annotations, # :background_color_legend, diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index f5ee90fa..d74357e7 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -1,6 +1,10 @@ # https://plot.ly/javascript/getting-started +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) +end + const _plotly_attr = merge_with_base_supported([ :annotations, :background_color_legend, :background_color_inside, :background_color_outside, diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 0776dbf1..1bcc3845 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -1,3 +1,6 @@ +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl")) +end # https://github.com/spencerlyon2/PlotlyJS.jl diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index e3b70eb9..4a8c3c95 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1,6 +1,9 @@ # https://github.com/stevengj/PyPlot.jl +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pyplot.jl")) +end const _pyplot_attr = merge_with_base_supported([ :annotations, diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index f5e34834..99482750 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -1,6 +1,10 @@ # https://github.com/Evizero/UnicodePlots.jl +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "unicodeplots.jl")) +end + const _unicodeplots_attr = merge_with_base_supported([ :label, :legend, diff --git a/src/backends/web.jl b/src/backends/web.jl index b0be7a3e..36fd5d06 100644 --- a/src/backends/web.jl +++ b/src/backends/web.jl @@ -2,7 +2,9 @@ # NOTE: backend should implement `html_body` and `html_head` # CREDIT: parts of this implementation were inspired by @joshday's PlotlyLocal.jl - +@require Revise begin + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "web.jl")) +end function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr, :window_title, "Plots.jl")) """ diff --git a/src/output.jl b/src/output.jl index 37849d8b..88caeeee 100644 --- a/src/output.jl +++ b/src/output.jl @@ -258,7 +258,6 @@ end const _ijulia_output = String["text/html"] -using Requires @require IJulia begin if IJulia.inited export set_ijulia_output From 133052b58c45da62119c56c85138dd9b2abe0486 Mon Sep 17 00:00:00 2001 From: Andy Nowacki Date: Thu, 19 Oct 2017 11:23:23 +0100 Subject: [PATCH 443/720] Animations: improve movie compatibility when using ffmpeg Add the -pix_fmt yuv420p option when using ffmpeg to save animations with the mov or mp4 commands. This improves compatibility of the movie files since many players do not support the ffmpeg defaults. To do this, add a third positional argument to `buildanimation` to specify if we want an animated GIF file. The default is `true`. See the following for more information: - https://trac.ffmpeg.org/wiki/Encode/H.264 ('Compatibility') - https://apple.stackexchange.com/questions/166553/why-wont-video-from-ffmpeg-show-in-quicktime-imovie-or-quick-preview --- src/animation.jl | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 0f539b01..8d3c0341 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -61,18 +61,23 @@ end file_extension(fn) = Base.Filesystem.splitext(fn)[2][2:end] gif(anim::Animation, fn = giffn(); kw...) = buildanimation(anim.dir, fn; kw...) -mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim.dir, fn; kw...) -mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn; kw...) +mov(anim::Animation, fn = movfn(); kw...) = buildanimation(anim.dir, fn, false; kw...) +mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn, false; kw...) -function buildanimation(animdir::AbstractString, fn::AbstractString; +function buildanimation(animdir::AbstractString, fn::AbstractString, + is_animated_gif::Bool=true; fps::Integer = 20, loop::Integer = 0) fn = abspath(fn) - # generate a colorpalette first so ffmpeg does not have to guess it - run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.png`) - # then apply the palette to get better results - run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.png -lavfi paletteuse -y $fn`) + if is_animated_gif + # generate a colorpalette first so ffmpeg does not have to guess it + run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.png`) + # then apply the palette to get better results + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.png -lavfi paletteuse -y $fn`) + else + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`) + end info("Saved animation to ", fn) AnimatedGif(fn) From ad6b707abfd0528a17ba7a3d2de16bc7fffdd121 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 24 Oct 2017 19:50:18 +0200 Subject: [PATCH 444/720] gr: implement title location --- src/backends/gr.jl | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index facfeb7f..ef539066 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -863,9 +863,20 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.savestate() if sp[:title] != "" gr_set_font(sp[:titlefont]) - GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP) + loc = sp[:title_location] + if loc == :left + xpos = viewport_plotarea[1] + halign = GR.TEXT_HALIGN_LEFT + elseif loc == :right + xpos = viewport_plotarea[2] + halign = GR.TEXT_HALIGN_RIGHT + else + xpos = gr_view_xcenter() + halign = GR.TEXT_HALIGN_CENTER + end + GR.settextalign(halign, GR.TEXT_VALIGN_TOP) gr_set_textcolor(sp[:foreground_color_title]) - gr_text(gr_view_xcenter(), viewport_subplot[4], sp[:title]) + gr_text(xpos, viewport_subplot[4], sp[:title]) end if xaxis[:guide] != "" From 7b6b44b2847029dbe6e8f9bf3fd2872a31d159ea Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 27 Oct 2017 15:52:32 +0200 Subject: [PATCH 445/720] add hline to pgfplots --- src/backends/pgfplots.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 2ae69b3f..ef009fe1 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -41,7 +41,7 @@ const _pgfplots_attr = merge_with_base_supported([ ]) 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_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline] #vcat(_allMarkers, Shape) const _pgfplots_scale = [:identity, :ln, :log2, :log10] @@ -86,6 +86,7 @@ const _pgfplots_markers = KW( :star6 => "asterisk", :diamond => "diamond*", :pentagon => "pentagon*", + :hline => "-" ) const _pgfplots_legend_pos = KW( From 5a3779e431ff5557dce6461e90ec68d05b4d65d9 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 30 Oct 2017 10:49:22 +0100 Subject: [PATCH 446/720] fill = true fills to 0 --- src/args.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/args.jl b/src/args.jl index 81cf03f8..afef5aeb 100644 --- a/src/args.jl +++ b/src/args.jl @@ -695,6 +695,9 @@ function processFillArg(d::KW, arg) arg.color == nothing || (d[:fillcolor] = arg.color == :auto ? :auto : plot_color(arg.color)) arg.alpha == nothing || (d[:fillalpha] = arg.alpha) + elseif typeof(arg) <: Bool + d[:fillrange] = arg ? 0 : nothing + # fillrange function elseif allFunctions(arg) d[:fillrange] = arg From a3e599e38d842919a1ee12508fdc396ca40f14ac Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Mon, 30 Oct 2017 19:50:02 +0000 Subject: [PATCH 447/720] Fix colorbar always displaying in Plotly. --- src/backends/plotly.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index d74357e7..b15e82c0 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -526,7 +526,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:type] = "heatmap" # d_out[:x], d_out[:y], d_out[:z] = series[:x], series[:y], transpose_z(series, series[:z].surf, false) d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) - d_out[:showscale] = sp[:legend] != :none + d_out[:showscale] = hascolorbar(sp) elseif st == :contour d_out[:type] = "contour" @@ -535,7 +535,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:ncontours] = series[:levels] d_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines") d_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha]) - d_out[:showscale] = sp[:legend] != :none + d_out[:showscale] = hascolorbar(sp) elseif st in (:surface, :wireframe) d_out[:type] = "surface" @@ -555,7 +555,7 @@ function plotly_series(plt::Plot, series::Series) if series[:fill_z] != nothing d_out[:surfacecolor] = plotly_surface_data(series, series[:fill_z]) end - d_out[:showscale] = sp[:legend] != :none + d_out[:showscale] = hascolorbar(sp) end elseif st == :pie From 4f171e3eb540e8fca41246708c3f88bb06550645 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 2 Nov 2017 16:32:57 +0000 Subject: [PATCH 448/720] Add handling of polar axes. --- src/axes.jl | 20 +++++++++++++++++--- src/backends/pgfplots.jl | 7 +++++-- src/backends/plotly.jl | 19 +++++++++++++++++++ src/backends/pyplot.jl | 5 +++++ 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 4288cde3..7ca04d2b 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -239,8 +239,13 @@ function get_ticks(axis::Axis) # discrete ticks... axis[:continuous_values], dvals elseif ticks == :auto - # compute optimal ticks and labels - optimal_ticks_and_labels(axis) + if ispolar(axis.sps[1]) && axis[:letter] == :x + #force theta axis to be full circle + (collect(0:pi/4:7pi/4), string.(0:45:315)) + else + # compute optimal ticks and labels + optimal_ticks_and_labels(axis) + end elseif typeof(ticks) <: Union{AVec, Int} # override ticks, but get the labels optimal_ticks_and_labels(axis, ticks) @@ -427,7 +432,16 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis) if !isfinite(amin) && !isfinite(amax) amin, amax = 0.0, 1.0 end - if should_widen + if ispolar(axis.sps[1]) + if axis[:letter] == :x + amin, amax = 0, 2pi + elseif lims == :auto + #widen max radius so ticks dont overlap with theta axis + amin, 1.1*amax + else + amin, amax + end + elseif should_widen widen(amin, amax) else amin, amax diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index ef009fe1..5f73a674 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -220,6 +220,8 @@ function pgf_series(sp::Subplot, series::Series) # If a marker_z is used pass it as third coordinate to a 2D plot. # See "Scatter Plots" in PGFPlots documentation d[:x], d[:y], d[:marker_z] + elseif ispolar(sp) + rad2deg.(d[:x]), d[:y] else d[:x], d[:y] end @@ -297,14 +299,15 @@ function pgf_axis(sp::Subplot, letter) # limits # TODO: support zlims if letter != :z - lims = axis_limits(axis) + lims = ispolar(sp) && letter == :x ? rad2deg.(axis_limits(axis)) : axis_limits(axis) kw[Symbol(letter,:min)] = lims[1] kw[Symbol(letter,:max)] = lims[2] end if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none ticks = get_ticks(axis) - push!(style, string(letter, "tick = {", join(ticks[1],","), "}")) + tick_values = ispolar(sp) && letter == :x ? rad2deg.(ticks[1]) : ticks[1] + push!(style, string(letter, "tick = {", join(tick_values,","), "}")) if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto # wrap the power part of label with } tick_labels = String[begin diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b15e82c0..e06f4151 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -291,6 +291,22 @@ function plotly_axis(axis::Axis, sp::Subplot) ax end +function plotly_polaraxis(axis::Axis) + ax = KW( + :visible => axis[:grid], + :showline => axis[:grid], + ) + + if axis[:letter] == :x + ax[:range] = rad2deg.(axis_limits(axis)) + else + ax[:range] = axis_limits(axis) + ax[:orientation] = 0 + end + + ax +end + function plotly_layout(plt::Plot) d_out = KW() @@ -345,6 +361,9 @@ function plotly_layout(plt::Plot) ), ), ) + elseif ispolar(sp) + d_out[Symbol("angularaxis$spidx")] = plotly_polaraxis(sp[:xaxis]) + d_out[Symbol("radialaxis$spidx")] = plotly_polaraxis(sp[:yaxis]) else d_out[Symbol("xaxis$spidx")] = plotly_axis(sp[:xaxis], sp) d_out[Symbol("yaxis$spidx")] = plotly_axis(sp[:yaxis], sp) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 4a8c3c95..9022a692 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1054,6 +1054,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) end py_set_scale(ax, axis) py_set_lims(ax, axis) + if ispolar(sp) && letter == :y + ax[:set_rlabel_position](0) + end ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis) # don't show the 0 tick label for the origin framestyle if sp[:framestyle] == :origin && length(ticks) > 1 @@ -1080,6 +1083,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) linewidth = axis[:gridlinewidth], alpha = axis[:gridalpha]) ax[:set_axisbelow](true) + else + pyaxis[:grid](false) end py_set_axis_colors(sp, ax, axis) end From 12aa43ff5f2239e02d038695c0729b86e868e04b Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 2 Nov 2017 16:33:05 +0000 Subject: [PATCH 449/720] Fix deprecations. --- src/backends/inspectdr.jl | 2 +- src/backends/plotly.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index da7bc144..7d09045a 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -245,7 +245,7 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) #No support for polar grid... but can still perform polar transformation: if ispolar(sp) Θ = x; r = y - x = r.*cos(Θ); y = r.*sin(Θ) + x = r.*cos.(Θ); y = r.*sin.(Θ) end # doesn't handle mismatched x/y - wrap data (pyplot behaviour): diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index e06f4151..96c54c9c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -717,7 +717,7 @@ end function plotly_polar!(d_out::KW, series::Series) # convert polar plots x/y to theta/radius if ispolar(series[:subplot]) - d_out[:t] = rad2deg(pop!(d_out, :x)) + d_out[:t] = rad2deg.(pop!(d_out, :x)) d_out[:r] = pop!(d_out, :y) end end From f690961af2435c84e041163ed6a2217e973d3933 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 2 Nov 2017 20:12:11 +0100 Subject: [PATCH 450/720] gr: use correct aspect ratio (fixes #1219) --- src/backends/gr.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ef539066..95dfcbde 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -412,6 +412,9 @@ function gr_viewport_from_bbox(sp::Subplot{GRBackend}, bb::BoundingBox, w, h, vi viewport[3] = 0.5 * (vp[3] + vp[4] - extent) viewport[4] = 0.5 * (vp[3] + vp[4] + extent) end + if hascolorbar(sp) + viewport[2] -= (viewport[2] - viewport[1]) * 0.1 + end viewport end @@ -687,11 +690,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end end - if cmap - # note: add extra midpadding on the right for the colorbar - viewport_plotarea[2] -= 0.1 - end - # set our plot area view gr_set_viewport_plotarea() From 5d5d8f073ae7c38d9a7b16e56e427c743706d297 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 2 Nov 2017 20:38:06 +0100 Subject: [PATCH 451/720] allow setting the linewidth for contour plots in GR --- src/backends/gr.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ef539066..dfc726bd 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -4,7 +4,7 @@ # significant contributions by @jheinen @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "gr.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "gr.jl")) end const _gr_attr = merge_with_base_supported([ @@ -997,11 +997,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else + GR.setlinewidth(series[:linewidth]) GR.contour(x, y, h, z, 1000) end # create the colorbar of contour levels if cmap + gr_set_line(1, :solid, yaxis[:foreground_color_axis]) gr_set_viewport_cmap(sp) l = round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) GR.setwindow(xmin, xmax, zmin, zmax) From b34f4141a2c25581aa248c702890b6cb62c89739 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Thu, 2 Nov 2017 21:53:11 +0100 Subject: [PATCH 452/720] Update gr.jl --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 95dfcbde..359f2727 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -413,7 +413,7 @@ function gr_viewport_from_bbox(sp::Subplot{GRBackend}, bb::BoundingBox, w, h, vi viewport[4] = 0.5 * (vp[3] + vp[4] + extent) end if hascolorbar(sp) - viewport[2] -= (viewport[2] - viewport[1]) * 0.1 + viewport[2] -= 0.1 end viewport end From 40282ae23ab55480b2acfe9e0d1465c7e6539b67 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 3 Nov 2017 10:02:16 +0100 Subject: [PATCH 453/720] allow setting the linestyle for contours on GR --- src/backends/gr.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index dfc726bd..9fc65c27 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -997,7 +997,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else - GR.setlinewidth(series[:linewidth]) + GR.setlinetype(gr_linetype[series[:linestyle]]) + width, height = gr_plot_size + GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) GR.contour(x, y, h, z, 1000) end From 8dd264c4da66170043be667882ad0e8ba0dcc60f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 3 Nov 2017 10:15:55 +0100 Subject: [PATCH 454/720] remove unnecessary line --- src/backends/gr.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9fc65c27..7df19ff0 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -998,7 +998,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else GR.setlinetype(gr_linetype[series[:linestyle]]) - width, height = gr_plot_size GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) GR.contour(x, y, h, z, 1000) end From f0ad851aa7a7c47d490073e552a4637dfe12d755 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 3 Nov 2017 19:45:17 +0000 Subject: [PATCH 455/720] Make radial axis vertical. --- src/backends/pgfplots.jl | 9 +++++++-- src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 5f73a674..e0f35f4d 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -306,7 +306,8 @@ function pgf_axis(sp::Subplot, letter) if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none ticks = get_ticks(axis) - tick_values = ispolar(sp) && letter == :x ? rad2deg.(ticks[1]) : ticks[1] + #pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values + tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 415] : ticks[1] push!(style, string(letter, "tick = {", join(tick_values,","), "}")) if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto # wrap the power part of label with } @@ -317,7 +318,8 @@ function pgf_axis(sp::Subplot, letter) end for label in ticks[2]] push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}")) elseif axis[:showaxis] - push!(style, string(letter, "ticklabels = {", join(ticks[2],","), "}")) + tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2] + push!(style, string(letter, "ticklabels = {", join(tick_labels,","), "}")) else push!(style, string(letter, "ticklabels = {}")) end @@ -405,6 +407,9 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) axisf = PGFPlots.Axis if sp[:projection] == :polar axisf = PGFPlots.PolarAxis + #make radial axis vertical + kw[:xmin] = 90 + kw[:xmax] = 450 end # Search series for any gradient. In case one series uses a gradient set diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 96c54c9c..940e36f6 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -301,7 +301,7 @@ function plotly_polaraxis(axis::Axis) ax[:range] = rad2deg.(axis_limits(axis)) else ax[:range] = axis_limits(axis) - ax[:orientation] = 0 + ax[:orientation] = -90 end ax diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 9022a692..86a8b5a0 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1055,7 +1055,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) py_set_scale(ax, axis) py_set_lims(ax, axis) if ispolar(sp) && letter == :y - ax[:set_rlabel_position](0) + ax[:set_rlabel_position](90) end ticks = sp[:framestyle] == :none ? nothing : get_ticks(axis) # don't show the 0 tick label for the origin framestyle From 2fe2ff474c3871400300371847709fa9e2859a59 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 4 Nov 2017 21:27:02 +0000 Subject: [PATCH 456/720] Implement grid attributes for polar plots. --- src/backends/gr.jl | 85 +++++++++++++++++++++++++++------------- src/backends/pgfplots.jl | 2 + src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 10 ++++- 4 files changed, 69 insertions(+), 30 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ef539066..cfb6e85d 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -205,35 +205,66 @@ function gr_text(x, y, s) end end -function gr_polaraxes(rmin, rmax) +function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) GR.savestate() - GR.setlinetype(GR.LINETYPE_SOLID) - GR.setlinecolorind(88) + xaxis = sp[:xaxis] + yaxis = sp[:yaxis] + + α = 0:45:315 + a = α .+ 90 + sinf = sind.(a) + cosf = cosd.(a) tick = 0.5 * GR.tick(rmin, rmax) n = round(Int, (rmax - rmin) / tick + 0.5) - for i in 0:n - r = float(i) / n - if i % 2 == 0 - GR.setlinecolorind(88) - if i > 0 - GR.drawarc(-r, r, -r, r, 0, 359) - end - GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) - x, y = GR.wctondc(0.05, r) - GR.text(x, y, string(signif(rmin + i * tick, 12))) - else - GR.setlinecolorind(90) - GR.drawarc(-r, r, -r, r, 0, 359) + + #draw angular grid + if xaxis[:grid] + gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) + GR.settransparency(xaxis[:gridalpha]) + for i in 1:length(α) + GR.polyline([sinf[i], 0], [cosf[i], 0]) end end - for α in 0:45:315 - a = α + 90 - sinf = sin(a * pi / 180) - cosf = cos(a * pi / 180) - GR.polyline([sinf, 0], [cosf, 0]) - GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) - x, y = GR.wctondc(1.1 * sinf, 1.1 * cosf) - GR.textext(x, y, string(α, "^o")) + + #draw radial grid + if yaxis[:grid] + gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) + GR.settransparency(yaxis[:gridalpha]) + for i in 0:n + r = float(i) / n + if i % 2 == 0 + if i > 0 + GR.drawarc(-r, r, -r, r, 0, 359) + end + else + GR.drawarc(-r, r, -r, r, 0, 359) + end + end + end + + #prepare to draw ticks + GR.settransparency(1) + GR.setlinecolorind(90) + GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) + + #draw angular ticks + if xaxis[:showaxis] + GR.drawarc(-1, 1, -1, 1, 0, 359) + for i in 1:length(α) + x, y = GR.wctondc(1.1 * sinf[i], 1.1 * cosf[i]) + GR.textext(x, y, string((360-α[i])%360, "^o")) + end + end + + #draw radial ticks + if yaxis[:showaxis] + for i in 0:n + r = float(i) / n + if i % 2 == 0 + x, y = GR.wctondc(0.05, r) + GR.text(x, y, string(signif(rmin + i * tick, 12))) + end + end end GR.restorestate() end @@ -760,9 +791,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif ispolar(sp) r = gr_set_viewport_polar() - rmin, rmax = GR.adjustrange(ignorenan_minimum(r), ignorenan_maximum(r)) - # rmin, rmax = axis_limits(sp[:yaxis]) - gr_polaraxes(rmin, rmax) + #rmin, rmax = GR.adjustrange(ignorenan_minimum(r), ignorenan_maximum(r)) + rmin, rmax = axis_limits(sp[:yaxis]) + gr_polaraxes(rmin, rmax, sp) elseif draw_axes if xmax > xmin && ymax > ymin diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index e0f35f4d..da527f9a 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -294,6 +294,8 @@ function pgf_axis(sp::Subplot, letter) # grid on or off if axis[:grid] && framestyle != :none push!(style, "$(letter)majorgrids = true") + else + push!(style, "$(letter)majorgrids = false") end # limits diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 940e36f6..9ada51f7 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -293,7 +293,7 @@ end function plotly_polaraxis(axis::Axis) ax = KW( - :visible => axis[:grid], + :visible => axis[:showaxis], :showline => axis[:grid], ) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 86a8b5a0..d325b21b 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1093,7 +1093,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if !sp[:xaxis][:showaxis] kw = KW() for dir in (:top, :bottom) - ax[:spines][string(dir)][:set_visible](false) + if ispolar(sp) + ax[:spines]["polar"][:set_visible](false) + else + ax[:spines][string(dir)][:set_visible](false) + end kw[dir] = kw[Symbol(:label,dir)] = "off" end ax[:xaxis][:set_tick_params](; which="both", kw...) @@ -1101,7 +1105,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if !sp[:yaxis][:showaxis] kw = KW() for dir in (:left, :right) - ax[:spines][string(dir)][:set_visible](false) + if !ispolar(sp) + ax[:spines][string(dir)][:set_visible](false) + end kw[dir] = kw[Symbol(:label,dir)] = "off" end ax[:yaxis][:set_tick_params](; which="both", kw...) From 8fb3f3b1c93f611a12ac8549cc91892a05c37251 Mon Sep 17 00:00:00 2001 From: Hessam Mehr Date: Sat, 4 Nov 2017 15:19:03 -0700 Subject: [PATCH 457/720] Fixed for #1138 --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b15e82c0..dc59fe5f 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -728,7 +728,7 @@ end const _use_remote = Ref(false) function html_head(plt::Plot{PlotlyBackend}) - jsfilename = _use_remote[] ? _plotly_js_path_remote : _plotly_js_path + jsfilename = _use_remote[] ? _plotly_js_path_remote : ("file://" * _plotly_js_path) # "" "" end From cc43202e8f854648cd00e498e9ffe138665c6d5f Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 4 Nov 2017 23:04:49 +0000 Subject: [PATCH 458/720] Fix radial axis tick alignment for GR. --- src/backends/gr.jl | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index cfb6e85d..b31a37ca 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -231,15 +231,12 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) GR.settransparency(yaxis[:gridalpha]) for i in 0:n - r = float(i) / n - if i % 2 == 0 - if i > 0 - GR.drawarc(-r, r, -r, r, 0, 359) - end - else + r = float(i) * tick / rmax + if r <= 1.0 GR.drawarc(-r, r, -r, r, 0, 359) end end + GR.drawarc(-1, 1, -1, 1, 0, 359) end #prepare to draw ticks @@ -259,8 +256,8 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw radial ticks if yaxis[:showaxis] for i in 0:n - r = float(i) / n - if i % 2 == 0 + r = float(i) * tick / rmax + if i % 2 == 0 && r <= 1.0 x, y = GR.wctondc(0.05, r) GR.text(x, y, string(signif(rmin + i * tick, 12))) end From 08a6f3af3659309875097cf90018f33f517dbafc Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 5 Nov 2017 10:37:51 +0000 Subject: [PATCH 459/720] Allow custom radial ticks for GR. Fix polar ylims for non-zero ymin values in GR. --- src/backends/gr.jl | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b31a37ca..9c21cf3e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -214,8 +214,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) a = α .+ 90 sinf = sind.(a) cosf = cosd.(a) - tick = 0.5 * GR.tick(rmin, rmax) - n = round(Int, (rmax - rmin) / tick + 0.5) + rtick_values, rtick_labels = get_ticks(yaxis) #draw angular grid if xaxis[:grid] @@ -230,9 +229,9 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) GR.settransparency(yaxis[:gridalpha]) - for i in 0:n - r = float(i) * tick / rmax - if r <= 1.0 + for i in 1:length(rtick_values) + r = (rtick_values[i] - rmin) / (rmax - rmin) + if r <= 1.0 && r >= 0.0 GR.drawarc(-r, r, -r, r, 0, 359) end end @@ -255,11 +254,11 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw radial ticks if yaxis[:showaxis] - for i in 0:n - r = float(i) * tick / rmax - if i % 2 == 0 && r <= 1.0 + for i in 1:length(rtick_values) + r = (rtick_values[i] - rmin) / (rmax - rmin) + if r <= 1.0 && r >= 0.0 x, y = GR.wctondc(0.05, r) - GR.text(x, y, string(signif(rmin + i * tick, 12))) + gr_text(x, y, _cycle(rtick_labels, i)) end end end From 6d14a858a389ab50cdeb6e5f73eaac5f1b652b4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1ll=20Haraldsson?= Date: Tue, 7 Nov 2017 11:11:46 +0000 Subject: [PATCH 460/720] Typo? Guessing here, 0.2.0 must be really old? --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 05f416f6..966c3500 100644 --- a/NEWS.md +++ b/NEWS.md @@ -105,7 +105,7 @@ #### 0.11.0 - julia 0.6 compatibility -- matplotlib 0.2.0 compatibility +- matplotlib 2.0 compatibility - add inspectdr backend - improved histogram functionality: - added a `:stephist` and `:scatterhist` series type as well as ``:barhist` (the default) From 51d4630405a6db0081c174eb95930c6ff990e178 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 8 Nov 2017 22:02:40 +0100 Subject: [PATCH 461/720] change pgfplots legend symbol for shapes and filled plots --- src/backends/pgfplots.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index ef009fe1..93acf765 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -207,6 +207,9 @@ function pgf_series(sp::Subplot, series::Series) # add to legend? if sp[:legend] != :none && should_add_to_legend(series) kw[:legendentry] = d[:label] + if st == :shape || d[:fillrange] != nothing + push!(style, "area legend") + end else push!(style, "forget plot") end From 8bbdb0f1b8c784988a8b423c43291f6d44924d01 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 12 Nov 2017 18:08:40 +0000 Subject: [PATCH 462/720] Adds radial data filtering for points within axis limits. --- src/backends/pgfplots.jl | 3 ++- src/backends/plotly.jl | 5 +++-- src/utils.jl | 23 +++++++++++++++++------ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index da527f9a..43c15eab 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -221,7 +221,8 @@ function pgf_series(sp::Subplot, series::Series) # See "Scatter Plots" in PGFPlots documentation d[:x], d[:y], d[:marker_z] elseif ispolar(sp) - rad2deg.(d[:x]), d[:y] + theta, r = filter_radial_data(d[:x], d[:y], axis_limits(sp[:yaxis])) + rad2deg.(theta), r else d[:x], d[:y] end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9ada51f7..e9a662cc 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -717,8 +717,9 @@ end function plotly_polar!(d_out::KW, series::Series) # convert polar plots x/y to theta/radius if ispolar(series[:subplot]) - d_out[:t] = rad2deg.(pop!(d_out, :x)) - d_out[:r] = pop!(d_out, :y) + theta, r = filter_radial_data(pop!(d_out, :x), pop!(d_out, :y), axis_limits(series[:subplot][:yaxis])) + d_out[:t] = rad2deg.(theta) + d_out[:r] = r end end diff --git a/src/utils.jl b/src/utils.jl index 81cd3571..d19a2acb 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -363,15 +363,26 @@ end function convert_to_polar(x, y, r_extrema = calc_r_extrema(x, y)) rmin, rmax = r_extrema - phi, r = x, y + theta, r = filter_radial_data(x, y, r_extrema) r = (r - rmin) / (rmax - rmin) - n = max(length(phi), length(r)) - x = zeros(n) - y = zeros(n) + x = r.*cos.(theta) + y = r.*sin.(theta) + x, y +end + +# Filters radial data for points within the axis limits +function filter_radial_data(theta, r, r_extrema::Tuple{Real, Real}) + n = max(length(theta), length(r)) + rmin, rmax = r_extrema + x, y = zeros(n), zeros(n) for i in 1:n - x[i] = _cycle(r,i) * cos.(_cycle(phi,i)) - y[i] = _cycle(r,i) * sin.(_cycle(phi,i)) + x[i] = _cycle(theta, i) + y[i] = _cycle(r, i) end + points = map((a, b) -> (a, b), x, y) + filter!(a -> a[2] >= rmin && a[2] <= rmax, points) + x = map(a -> a[1], points) + y = map(a -> a[2], points) x, y end From 240c1efab9720148848896364cc6365df3695ae3 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 12 Nov 2017 18:09:08 +0000 Subject: [PATCH 463/720] Improve default radial axis padding. --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index 7ca04d2b..a3c3293c 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -437,7 +437,7 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis) amin, amax = 0, 2pi elseif lims == :auto #widen max radius so ticks dont overlap with theta axis - amin, 1.1*amax + amin, amax + 0.1 * abs(amax - amin) else amin, amax end From acf6e86c0fbb93e5c24d4f918a20dbcc6f8f4611 Mon Sep 17 00:00:00 2001 From: biggsbiggsby <33279473+biggsbiggsby@users.noreply.github.com> Date: Tue, 14 Nov 2017 09:39:59 +0100 Subject: [PATCH 464/720] gif animation.jl Change palette from png to gif to avoid png encoding bug in ffmpeg --- src/animation.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 8d3c0341..7faaa579 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -72,9 +72,9 @@ function buildanimation(animdir::AbstractString, fn::AbstractString, if is_animated_gif # generate a colorpalette first so ffmpeg does not have to guess it - run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.png`) + run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.gif`) # then apply the palette to get better results - run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.png -lavfi paletteuse -y $fn`) + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.gif -lavfi paletteuse -y $fn`) else run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`) end From 99f25ef744386d78cfa75b23b5f4f047ac7aa322 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Tue, 14 Nov 2017 13:49:53 +0000 Subject: [PATCH 465/720] Fix typo. --- 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 43c15eab..7f4fbba3 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -310,7 +310,7 @@ function pgf_axis(sp::Subplot, letter) if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none ticks = get_ticks(axis) #pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values - tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 415] : ticks[1] + tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ticks[1] push!(style, string(letter, "tick = {", join(tick_values,","), "}")) if axis[:showaxis] && axis[:scale] in (:ln, :log2, :log10) && axis[:ticks] == :auto # wrap the power part of label with } From ae37dce0f322f522ae4633eec8b7d381621d2a58 Mon Sep 17 00:00:00 2001 From: Huckleberry Febbo Date: Tue, 14 Nov 2017 13:43:17 -0500 Subject: [PATCH 466/720] allow legend to be outside for pgfplots() --- src/args.jl | 2 +- src/backends/pgfplots.jl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index afef5aeb..2bf63ac6 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1002,7 +1002,7 @@ function convertLegendValue(val::Symbol) :best elseif val in (:no, :none) :none - elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend, :topright, :topleft, :bottomleft, :bottomright) + elseif val in (:right, :left, :top, :bottom, :inside, :best, :legend, :topright, :topleft, :bottomleft, :bottomright, :outertopright) val else error("Invalid symbol for legend: $val") diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index d455b638..d83917d0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -94,6 +94,7 @@ const _pgfplots_legend_pos = KW( :bottomright => "south east", :topright => "north east", :topleft => "north west", + :outertopright => "outer north east", ) From cf58f3cbf238152d9a2b6b5199acb345588049dd Mon Sep 17 00:00:00 2001 From: biggsbiggsby <33279473+biggsbiggsby@users.noreply.github.com> Date: Fri, 17 Nov 2017 10:30:23 +0100 Subject: [PATCH 467/720] Update animation.jl Generates a color palette for each frame (instead of each animation) to improve quality, and avoid palette file format issues in FFMPEG 3.4 --- src/animation.jl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 7faaa579..760a56d2 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -71,10 +71,9 @@ function buildanimation(animdir::AbstractString, fn::AbstractString, fn = abspath(fn) if is_animated_gif - # generate a colorpalette first so ffmpeg does not have to guess it - run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf palettegen -y palette.gif`) - # then apply the palette to get better results - run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i palette.gif -lavfi paletteuse -y $fn`) + # generate a colorpalette for each frame to improve quality + palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1" + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`) else run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`) end From 1aa780f0a21218ba0ec34d6886e6ec0718efade9 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 17 Nov 2017 11:33:10 +0100 Subject: [PATCH 468/720] change legend symbols for shapes and filled plots on pyplot --- src/backends/pyplot.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d325b21b..a29b81b7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -2,7 +2,7 @@ # https://github.com/stevengj/PyPlot.jl @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pyplot.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "pyplot.jl")) end const _pyplot_attr = merge_with_base_supported([ @@ -1009,7 +1009,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) for lab in cb[:ax][:yaxis][:get_ticklabels]() lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) lab[:set_family](sp[:yaxis][:tickfont].family) - end + end sp.attr[:cbar_handle] = cb sp.attr[:cbar_ax] = cbax end @@ -1221,10 +1221,11 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) for series in series_list(sp) if should_add_to_legend(series) # add a line/marker and a label - push!(handles, if series[:seriestype] == :shape - PyPlot.plt[:Line2D]((0,1),(0,0), - color = py_color(_cycle(series[:fillcolor],1)), - linewidth = py_dpi_scale(plt, 4) + push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing + pypatches[:Patch]( + edgecolor = py_color(_cycle(series[:linecolor],1)), + facecolor = py_color(_cycle(series[:fillcolor],1)), + linewidth = py_dpi_scale(plt, series[:linewidth]) ) elseif series[:seriestype] == :path PyPlot.plt[:Line2D]((0,1),(0,0), From ee0f4e11ea1d81bbb08c1763c35d858bc105daf1 Mon Sep 17 00:00:00 2001 From: biggsbiggsby <33279473+biggsbiggsby@users.noreply.github.com> Date: Fri, 17 Nov 2017 12:35:36 +0100 Subject: [PATCH 469/720] Update animation.jl Changed palette for each frame to an option, made the default palette a lossless bmp file for best quality/filesize, but still compatible with FFMPEG 3.4 on Win7 x64 --- src/animation.jl | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 760a56d2..93f28427 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -67,13 +67,21 @@ mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn, false; function buildanimation(animdir::AbstractString, fn::AbstractString, is_animated_gif::Bool=true; - fps::Integer = 20, loop::Integer = 0) + fps::Integer = 20, loop::Integer = 0, + variable_palette::Bool=false) fn = abspath(fn) if is_animated_gif - # generate a colorpalette for each frame to improve quality - palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1" - run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`) + if variable_palette + # generate a colorpalette for each frame for highest quality, but larger filesize + palette="palettegen=stats_mode=single[pal],[0:v][pal]paletteuse=new=1" + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -lavfi "$palette" -y $fn`) + else + # generate a colorpalette first so ffmpeg does not have to guess it + run(`ffmpeg -v 0 -i $(animdir)/%06d.png -vf "palettegen=stats_mode=diff" -y "$(animdir)/palette.bmp"`) + # then apply the palette to get better results + run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -i "$(animdir)/palette.bmp" -lavfi "paletteuse=dither=sierra2_4a" -y $fn`) + end else run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`) end From 4bc01b92bd3f980899429f75bc24f104da9a73f6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 17 Nov 2017 12:59:20 +0100 Subject: [PATCH 470/720] avoid too big linewidths in legend --- src/backends/pyplot.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index a29b81b7..fcac84c6 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1225,12 +1225,12 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) pypatches[:Patch]( edgecolor = py_color(_cycle(series[:linecolor],1)), facecolor = py_color(_cycle(series[:fillcolor],1)), - linewidth = py_dpi_scale(plt, series[:linewidth]) + linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), ) elseif series[:seriestype] == :path - PyPlot.plt[:Line2D]((0,1),(0,0), + PyPlot.plt[:Line2D]((0, 1),(0,0), color = py_color(_cycle(series[:fillcolor],1)), - linewidth = py_dpi_scale(plt, 1), + linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), markerfacecolor = py_markercolor(series) From 4bfb56247714a5c656c3b7be1356a8515e8c9628 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 17 Nov 2017 13:01:13 +0100 Subject: [PATCH 471/720] remove extra space --- 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 fcac84c6..1ef9a2d7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1228,7 +1228,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), ) elseif series[:seriestype] == :path - PyPlot.plt[:Line2D]((0, 1),(0,0), + PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), marker = py_marker(series[:markershape]), From df023d6bdb42138029e4208db6c840957d775a2e Mon Sep 17 00:00:00 2001 From: Romain Franconville Date: Fri, 17 Nov 2017 15:02:16 -0500 Subject: [PATCH 472/720] Always define axis range explicitely --- src/backends/plotly.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 3b149a20..19c3ab14 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -252,7 +252,7 @@ function plotly_axis(axis::Axis, sp::Subplot) end ax[:tickangle] = -axis[:rotation] - + ax[:range] = axis_limits(axis) if !(axis[:ticks] in (nothing, :none)) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) @@ -288,6 +288,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:showgrid] = false end + ax end From c01d8199f9acd24f663769213b81d893c9e624b4 Mon Sep 17 00:00:00 2001 From: Romain Franconville Date: Fri, 17 Nov 2017 15:29:55 -0500 Subject: [PATCH 473/720] Also include scaling --- src/backends/plotly.jl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 19c3ab14..b7670449 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -252,7 +252,9 @@ function plotly_axis(axis::Axis, sp::Subplot) end ax[:tickangle] = -axis[:rotation] - ax[:range] = axis_limits(axis) + lims = axis_limits(axis) + ax[:range] = map(scalefunc(axis[:scale]), lims) + if !(axis[:ticks] in (nothing, :none)) ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) ax[:type] = plotly_scale(axis[:scale]) @@ -261,10 +263,10 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) # lims - lims = axis[:lims] - if lims != :auto && limsType(lims) == :limits - ax[:range] = map(scalefunc(axis[:scale]), lims) - end + + #if lims != :auto && limsType(lims) == :limits + #ax[:range] = map(scalefunc(axis[:scale]), lims) + #end # flip if axis[:flip] From 5a0744e2f137b2eec85e6616ad1fe454a5d733e6 Mon Sep 17 00:00:00 2001 From: Romain Franconville Date: Fri, 17 Nov 2017 16:06:14 -0500 Subject: [PATCH 474/720] Remove commented code --- src/backends/plotly.jl | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index b7670449..b0906444 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -262,12 +262,6 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) - # lims - - #if lims != :auto && limsType(lims) == :limits - #ax[:range] = map(scalefunc(axis[:scale]), lims) - #end - # flip if axis[:flip] ax[:autorange] = "reversed" From ea976d5f08d9be7c0ff8db26b987d8727bcca5d5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 12:53:11 +0100 Subject: [PATCH 475/720] expand axes extrema for heatmap edges --- src/axes.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/axes.jl b/src/axes.jl index a3c3293c..d4fac7cb 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -380,6 +380,15 @@ function expand_extrema!(sp::Subplot, d::KW) expand_extrema!(axis, ignorenan_minimum(data) - 0.5minimum(bw)) end + # expand for heatmaps + if d[:seriestype] == :heatmap + for letter in (:x, :y) + data = d[letter] + axis = sp[Symbol(letter, "axis")] + scale = get(d, Symbol(letter, "scale"), :identity) + expand_extrema!(axis, heatmap_edges(data, scale)) + end + end end function expand_extrema!(sp::Subplot, xmin, xmax, ymin, ymax) From 9f5be974b60ad8dccb59dbc61d434a8368f91aa7 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 14:02:49 +0100 Subject: [PATCH 476/720] add fontfamily, fontsize, fonthalign, fontvalign, fontrotation, fontcolor keywords --- src/args.jl | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/args.jl b/src/args.jl index 2bf63ac6..8c3159f9 100644 --- a/src/args.jl +++ b/src/args.jl @@ -273,6 +273,7 @@ const _plot_defaults = KW( :background_color => colorant"white", # default for all backgrounds, :background_color_outside => :match, # background outside grid, :foreground_color => :auto, # default for all foregrounds, and title color, + :fontfamily => "sans-serif", :size => (600,400), :pos => (0,0), :window_title => "Plots.jl", @@ -293,6 +294,12 @@ const _subplot_defaults = KW( :title => "", :title_location => :center, # also :left or :right :titlefont => font(14), + :titlefontfamily => :match, + :titlefontsize => 14, + :titlefonthalign => :hcenter, + :titlefontvalign => :vcenter, + :titlefontrotation => 0.0, + :titlefontcolor => :match, :background_color_subplot => :match, # default for other bg colors... match takes plot default :background_color_legend => :match, # background of legend :background_color_inside => :match, # background inside grid @@ -305,6 +312,12 @@ const _subplot_defaults = KW( :colorbar => :legend, :clims => :auto, :legendfont => font(8), + :legendfontfamily => :match, + :legendfontsize => 8, + :legendfonthalign => :hcenter, + :legendfontvalign => :vcenter, + :legendfontrotation => 0.0, + :legendfontcolor => :match, :annotations => [], # annotation tuples... list of (x,y,annotation) :projection => :none, # can also be :polar or :3d :aspect_ratio => :none, # choose from :none or :equal @@ -328,7 +341,19 @@ const _axis_defaults = KW( :flip => false, :link => [], :tickfont => font(8), + :tickfontfamily => :match, + :tickfontsize => 8, + :tickfonthalign => :hcenter, + :tickfontvalign => :vcenter, + :tickfontrotation => 0.0, + :tickfontcolor => :match, :guidefont => font(11), + :guidefontfamily => :match, + :guidefontsize => 11, + :guidefonthalign => :hcenter, + :guidefontvalign => :vcenter, + :guidefontrotation => 0.0, + :guidefontcolor => :match, :foreground_color_axis => :match, # axis border/tick colors, :foreground_color_border => :match, # plot area border/spines, :foreground_color_text => :match, # tick text color, @@ -1084,6 +1109,12 @@ const _match_map = KW( :top_margin => :margin, :right_margin => :margin, :bottom_margin => :margin, + :titlefontfamily => :fontfamily, + :labelfontfamily => :fontfamily, + :tickfontfamily => :fontfamily, + :guidefontfamily => :fontfamily, + :titlefontcolor => :foreground_color_subplot, + :labelfontcolor => :foreground_color_subplot, ) # these can match values from the parent container (axis --> subplot --> plot) @@ -1095,6 +1126,8 @@ const _match_map2 = KW( :foreground_color_grid => :foreground_color_subplot, :foreground_color_guide => :foreground_color_subplot, :foreground_color_text => :foreground_color_subplot, + :tickfontcolor => :foreground_color_text, + :guidefontcolor => :foreground_color_text, ) # properly retrieve from plt.attr, passing `:match` to the correct key From 68a060b7eb50121d62ce5578812e54719ae07eed Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 14:31:30 +0100 Subject: [PATCH 477/720] implement titlefont, legendfont, tickfont and guidefont magic keyword arguments --- src/args.jl | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/args.jl b/src/args.jl index 8c3159f9..b2c5958b 100644 --- a/src/args.jl +++ b/src/args.jl @@ -293,7 +293,6 @@ const _plot_defaults = KW( const _subplot_defaults = KW( :title => "", :title_location => :center, # also :left or :right - :titlefont => font(14), :titlefontfamily => :match, :titlefontsize => 14, :titlefonthalign => :hcenter, @@ -311,7 +310,6 @@ const _subplot_defaults = KW( :legendtitle => nothing, :colorbar => :legend, :clims => :auto, - :legendfont => font(8), :legendfontfamily => :match, :legendfontsize => 8, :legendfonthalign => :hcenter, @@ -340,14 +338,12 @@ const _axis_defaults = KW( :rotation => 0, :flip => false, :link => [], - :tickfont => font(8), :tickfontfamily => :match, :tickfontsize => 8, :tickfonthalign => :hcenter, :tickfontvalign => :vcenter, :tickfontrotation => 0.0, :tickfontcolor => :match, - :guidefont => font(11), :guidefontfamily => :match, :guidefontsize => 11, :guidefonthalign => :hcenter, @@ -768,6 +764,15 @@ function processGridArg!(d::KW, arg, letter) end end +processFontArgs!(d::KW, fontname::Symbol, args::Tuple) + fnt = font(args...) + d[Symbol(fontname, :family)] = fnt.family + d[Symbol(fontname, :size)] = fnt.pointsize + d[Symbol(fontname, :halign)] = fnt.halign + d[Symbol(fontname, :valign)] = fnt.valign + d[Symbol(fontname, :rotation)] = fnt.rotation + d[Symbol(fontname, :color)] = fnt.color +end _replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape) _replace_markershape(shapes::AVec) = map(_replace_markershape, shapes) @@ -836,6 +841,25 @@ function preprocessArgs!(d::KW) end end + # fonts + for fontname in (:titlefont, :legendfont) + args = pop!(d, fontname, ()) + processFontArgs!(d, fontname, args) + end + # handle font args common to all axes + for fontname in (:tickfont, :guidefont) + args = pop!(d, fontname, ()) + for letter in (:x, :y, :z) + processFontArgs!(d, Symbol(letter, fontname), args) + end + end + # handle individual axes font args + for letter in (:x, :y, :z) + for fontname in (:tickfont, :guidefont) + args = pop!(d, Symbol(letter, fontname), ()) + processFontArgs!(d, Symbol(letter, fontname), args) + end + # handle line args for arg in wraptuple(pop!(d, :line, ())) processLineArg(d, arg) From 8fee5e0de7cdb91362ee7b9531c4830b59d0f262 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 14:58:30 +0100 Subject: [PATCH 478/720] implement titlefont legendfont tickfont and guidefont functions to construct font objects from subplots and axes --- src/args.jl | 2 +- src/utils.jl | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/args.jl b/src/args.jl index b2c5958b..a5a63ad5 100644 --- a/src/args.jl +++ b/src/args.jl @@ -764,7 +764,7 @@ function processGridArg!(d::KW, arg, letter) end end -processFontArgs!(d::KW, fontname::Symbol, args::Tuple) +function processFontArgs!(d::KW, fontname::Symbol, args::Tuple) fnt = font(args...) d[Symbol(fontname, :family)] = fnt.family d[Symbol(fontname, :size)] = fnt.pointsize diff --git a/src/utils.jl b/src/utils.jl index d19a2acb..b9da48d5 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1007,3 +1007,43 @@ xmax(plt::Plot) = ignorenan_maximum([ignorenan_maximum(series.d[:x]) for series "Extrema of x-values in plot" ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt)) + + +# --------------------------------------------------------------- +# get fonts from objects: + +titlefont(sp::Subplot) = font( + sp[:titlefontfamily], + sp[:titlefontsize], + sp[:titlefont], + sp[:titlefonthalign], + sp[:titlefontrotation], + sp[:titlefontcolor], +) + +legendfont(sp::Subplot) = font( + sp[:legendfontfamily], + sp[:legendfontsize], + sp[:legendfont], + sp[:legendfonthalign], + sp[:legendfontrotation], + sp[:legendfontcolor], +) + +tickfont(ax::Axis) = font( + ax[:tickfontfamily], + ax[:tickfontsize], + ax[:tickfont], + ax[:tickfonthalign], + ax[:tickfontrotation], + ax[:tickfontcolor], +) + +guidefont(ax::Axis) = font( + ax[:guidefontfamily], + ax[:guidefontsize], + ax[:guidefont], + ax[:guidefonthalign], + ax[:guidefontrotation], + ax[:guidefontcolor], +) From ba3e75e710ce69a9dc5b0cc68f14febbfd074cfc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 15:16:49 +0100 Subject: [PATCH 479/720] fix errors --- src/args.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/args.jl b/src/args.jl index a5a63ad5..84f8a4bc 100644 --- a/src/args.jl +++ b/src/args.jl @@ -418,10 +418,10 @@ const _all_defaults = KW[ const _initial_defaults = deepcopy(_all_defaults) # to be able to reset font sizes to initial values -const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefont].pointsize, - :legendfont => _subplot_defaults[:legendfont].pointsize, - :tickfont => _axis_defaults[:tickfont].pointsize, - :guidefont => _axis_defaults[:guidefont].pointsize) +const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefontsize], + :legendfont => _subplot_defaults[:legendfontsize], + :tickfont => _axis_defaults[:tickfontsize], + :guidefont => _axis_defaults[:guidefontsize]) const _all_args = sort(collect(union(map(keys, _all_defaults)...))) @@ -856,8 +856,9 @@ function preprocessArgs!(d::KW) # handle individual axes font args for letter in (:x, :y, :z) for fontname in (:tickfont, :guidefont) - args = pop!(d, Symbol(letter, fontname), ()) - processFontArgs!(d, Symbol(letter, fontname), args) + args = pop!(d, Symbol(letter, fontname), ()) + processFontArgs!(d, Symbol(letter, fontname), args) + end end # handle line args From 0da6f6b4a45b99944739ba5515c5fa6a0918a25e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 15:32:30 +0100 Subject: [PATCH 480/720] update gr --- src/backends/gr.jl | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9619f638..6c5e486b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -22,7 +22,14 @@ const _gr_attr = merge_with_base_supported([ :layout, :title, :window_title, :guide, :lims, :ticks, :scale, :flip, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign, + :titlefontrotation, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfonthalign, :legendfontvalign, + :legendfontrotation, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfonthalign, :tickfontvalign, + :tickfontrotation, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefonthalign, :guidefontvalign, + :guidefontrotation, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, :fill_z, :line_z, :marker_z, :levels, @@ -583,10 +590,9 @@ end function gr_set_xticks_font(sp) flip = sp[:yaxis][:flip] mirror = sp[:xaxis][:mirror] - gr_set_font(sp[:xaxis][:tickfont], + gr_set_font(tickfont(sp[:xaxis]), halign = (:left, :hcenter, :right)[sign(sp[:xaxis][:rotation]) + 2], valign = (mirror ? :bottom : :top), - color = sp[:xaxis][:foreground_color_axis], rotation = sp[:xaxis][:rotation]) return flip, mirror end @@ -595,10 +601,9 @@ end function gr_set_yticks_font(sp) flip = sp[:xaxis][:flip] mirror = sp[:yaxis][:mirror] - gr_set_font(sp[:yaxis][:tickfont], + gr_set_font(tickfont(sp[:yaxis]), halign = (mirror ? :left : :right), valign = (:top, :vcenter, :bottom)[sign(sp[:yaxis][:rotation]) + 2], - color = sp[:yaxis][:foreground_color_axis], rotation = sp[:yaxis][:rotation]) return flip, mirror end @@ -759,8 +764,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end # draw the axes - gr_set_font(xaxis[:tickfont]) - gr_set_textcolor(xaxis[:foreground_color_text]) + gr_set_font(tickfont(xaxis)) GR.setlinewidth(1) if is3d(sp) @@ -887,7 +891,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # add the guides GR.savestate() if sp[:title] != "" - gr_set_font(sp[:titlefont]) + gr_set_font(titlefont(sp)) loc = sp[:title_location] if loc == :left xpos = viewport_plotarea[1] @@ -905,22 +909,20 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if xaxis[:guide] != "" - gr_set_font(xaxis[:guidefont]) + gr_set_font(guidefont(xaxis)) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_BOTTOM) - gr_set_textcolor(xaxis[:foreground_color_guide]) gr_text(gr_view_xcenter(), viewport_subplot[3], xaxis[:guide]) end if yaxis[:guide] != "" - gr_set_font(yaxis[:guidefont]) + gr_set_font(guidefont(yaxis)) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_TOP) GR.setcharup(-1, 0) - gr_set_textcolor(yaxis[:foreground_color_guide]) gr_text(viewport_subplot[1], gr_view_ycenter(), yaxis[:guide]) end GR.restorestate() - gr_set_font(xaxis[:tickfont]) + gr_set_font(tickfont(xaxis)) # this needs to be here to point the colormap to the right indices GR.setcolormap(1000 + GR.COLORMAP_COOLWARM) @@ -1193,7 +1195,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.savestate() GR.selntran(0) GR.setscale(0) - gr_set_font(sp[:legendfont]) + gr_set_font(legendfont(sp)) w = 0 i = 0 n = 0 @@ -1215,7 +1217,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) w = max(w, tbx[3] - tbx[1]) end if w > 0 - dy = _gr_point_mult[1] * sp[:legendfont].pointsize * 1.75 + dy = _gr_point_mult[1] * sp[:legendfontsize] * 1.75 h = dy*n (xpos,ypos) = gr_legend_pos(sp[:legend],w,h) GR.setfillintstyle(GR.INTSTYLE_SOLID) From 6e51a086943b3185bdd293a06d611ccfb81e0b3a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 15:36:11 +0100 Subject: [PATCH 481/720] fix errors --- src/args.jl | 2 +- src/utils.jl | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/args.jl b/src/args.jl index 84f8a4bc..f9621d76 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1152,7 +1152,7 @@ const _match_map2 = KW( :foreground_color_guide => :foreground_color_subplot, :foreground_color_text => :foreground_color_subplot, :tickfontcolor => :foreground_color_text, - :guidefontcolor => :foreground_color_text, + :guidefontcolor => :foreground_color_guide, ) # properly retrieve from plt.attr, passing `:match` to the correct key diff --git a/src/utils.jl b/src/utils.jl index b9da48d5..c5a4baa0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1015,7 +1015,7 @@ ignorenan_extrema(plt::Plot) = (xmin(plt), xmax(plt)) titlefont(sp::Subplot) = font( sp[:titlefontfamily], sp[:titlefontsize], - sp[:titlefont], + sp[:titlefontvalign], sp[:titlefonthalign], sp[:titlefontrotation], sp[:titlefontcolor], @@ -1024,7 +1024,7 @@ titlefont(sp::Subplot) = font( legendfont(sp::Subplot) = font( sp[:legendfontfamily], sp[:legendfontsize], - sp[:legendfont], + sp[:legendfontvalign], sp[:legendfonthalign], sp[:legendfontrotation], sp[:legendfontcolor], @@ -1033,7 +1033,7 @@ legendfont(sp::Subplot) = font( tickfont(ax::Axis) = font( ax[:tickfontfamily], ax[:tickfontsize], - ax[:tickfont], + ax[:tickfontvalign], ax[:tickfonthalign], ax[:tickfontrotation], ax[:tickfontcolor], @@ -1042,7 +1042,7 @@ tickfont(ax::Axis) = font( guidefont(ax::Axis) = font( ax[:guidefontfamily], ax[:guidefontsize], - ax[:guidefont], + ax[:guidefontvalign], ax[:guidefonthalign], ax[:guidefontrotation], ax[:guidefontcolor], From e80a73cc1c7c90a56734b752c89cd195f3e6df7a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 16:59:54 +0100 Subject: [PATCH 482/720] fix magic font argument and cascading font defaults --- src/args.jl | 69 +++++++++++++++++++++++++++++++++------------- src/backends/gr.jl | 5 ++-- 2 files changed, 52 insertions(+), 22 deletions(-) diff --git a/src/args.jl b/src/args.jl index f9621d76..df11cabf 100644 --- a/src/args.jl +++ b/src/args.jl @@ -293,6 +293,7 @@ const _plot_defaults = KW( const _subplot_defaults = KW( :title => "", :title_location => :center, # also :left or :right + :fontfamily_subplot => :match, :titlefontfamily => :match, :titlefontsize => 14, :titlefonthalign => :hcenter, @@ -764,14 +765,37 @@ function processGridArg!(d::KW, arg, letter) end end -function processFontArgs!(d::KW, fontname::Symbol, args::Tuple) - fnt = font(args...) - d[Symbol(fontname, :family)] = fnt.family - d[Symbol(fontname, :size)] = fnt.pointsize - d[Symbol(fontname, :halign)] = fnt.halign - d[Symbol(fontname, :valign)] = fnt.valign - d[Symbol(fontname, :rotation)] = fnt.rotation - d[Symbol(fontname, :color)] = fnt.color +function processFontArg!(d::KW, fontname::Symbol, arg) + T = typeof(arg) + if T <: Font + d[Symbol(fontname, :family)] = arg.family + d[Symbol(fontname, :size)] = arg.pointsize + d[Symbol(fontname, :halign)] = arg.halign + d[Symbol(fontname, :valign)] = arg.valign + d[Symbol(fontname, :rotation)] = arg.rotation + d[Symbol(fontname, :color)] = arg.color + elseif arg == :center + d[Symbol(fontname, :halign)] = :hcenter + d[Symbol(fontname, :valign)] = :vcenter + elseif arg in (:hcenter, :left, :right) + d[Symbol(fontname, :halign)] = arg + elseif arg in (:vcenter, :top, :bottom) + d[Symbol(fontname, :valign)] = arg + elseif T <: Colorant + d[Symbol(fontname, :color)] = arg + elseif T <: Symbol || T <: AbstractString + try + d[Symbol(fontname, :color)] = parse(Colorant, string(arg)) + catch + d[Symbol(fontname, :family)] = string(arg) + end + elseif typeof(arg) <: Integer + d[Symbol(fontname, :size)] = arg + elseif typeof(arg) <: Real + d[Symbol(fontname, :rotation)] = convert(Float64, arg) + else + warn("Skipped font arg: $arg ($(typeof(arg)))") + end end _replace_markershape(shape::Symbol) = get(_markerAliases, shape, shape) @@ -844,20 +868,26 @@ function preprocessArgs!(d::KW) # fonts for fontname in (:titlefont, :legendfont) args = pop!(d, fontname, ()) - processFontArgs!(d, fontname, args) + for arg in wraptuple(args) + processFontArg!(d, fontname, arg) + end end # handle font args common to all axes for fontname in (:tickfont, :guidefont) args = pop!(d, fontname, ()) - for letter in (:x, :y, :z) - processFontArgs!(d, Symbol(letter, fontname), args) + for arg in wraptuple(args) + for letter in (:x, :y, :z) + processFontArg!(d, Symbol(letter, fontname), arg) + end end end # handle individual axes font args for letter in (:x, :y, :z) for fontname in (:tickfont, :guidefont) args = pop!(d, Symbol(letter, fontname), ()) - processFontArgs!(d, Symbol(letter, fontname), args) + for arg in wraptuple(args) + processFontArg!(d, Symbol(letter, fontname), arg) + end end end @@ -1134,12 +1164,12 @@ const _match_map = KW( :top_margin => :margin, :right_margin => :margin, :bottom_margin => :margin, - :titlefontfamily => :fontfamily, - :labelfontfamily => :fontfamily, - :tickfontfamily => :fontfamily, - :guidefontfamily => :fontfamily, + :titlefontfamily => :fontfamily_subplot, + :legendfontfamily => :fontfamily_subplot, :titlefontcolor => :foreground_color_subplot, - :labelfontcolor => :foreground_color_subplot, + :legendfontcolor => :foreground_color_subplot, + :tickfontcolor => :foreground_color_text, + :guidefontcolor => :foreground_color_guide, ) # these can match values from the parent container (axis --> subplot --> plot) @@ -1151,8 +1181,9 @@ const _match_map2 = KW( :foreground_color_grid => :foreground_color_subplot, :foreground_color_guide => :foreground_color_subplot, :foreground_color_text => :foreground_color_subplot, - :tickfontcolor => :foreground_color_text, - :guidefontcolor => :foreground_color_guide, + :fontfamily_subplot => :fontfamily, + :tickfontfamily => :fontfamily_subplot, + :guidefontfamily => :fontfamily_subplot, ) # properly retrieve from plt.attr, passing `:match` to the correct key diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6c5e486b..7261ca2c 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -904,7 +904,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) halign = GR.TEXT_HALIGN_CENTER end GR.settextalign(halign, GR.TEXT_VALIGN_TOP) - gr_set_textcolor(sp[:foreground_color_title]) gr_text(xpos, viewport_subplot[4], sp[:title]) end @@ -1229,7 +1228,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) i = 0 if sp[:legendtitle] != nothing GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) - gr_set_textcolor(sp[:foreground_color_legend]) + gr_set_textcolor(sp[:legendfontcolor]) GR.settransparency(1) gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) ypos -= dy @@ -1271,7 +1270,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) lab = series[:label] end GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) - gr_set_textcolor(sp[:foreground_color_legend]) + gr_set_textcolor(sp[:legendfontcolor]) gr_text(xpos, ypos, lab) ypos -= dy end From 60d20ea998d341080b9be78e91173297690b73ff Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 18:15:22 +0100 Subject: [PATCH 483/720] update pyplot --- src/args.jl | 12 ++++++------ src/backends/pyplot.jl | 36 +++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/args.jl b/src/args.jl index df11cabf..70fa458c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1164,12 +1164,12 @@ const _match_map = KW( :top_margin => :margin, :right_margin => :margin, :bottom_margin => :margin, - :titlefontfamily => :fontfamily_subplot, - :legendfontfamily => :fontfamily_subplot, - :titlefontcolor => :foreground_color_subplot, - :legendfontcolor => :foreground_color_subplot, - :tickfontcolor => :foreground_color_text, - :guidefontcolor => :foreground_color_guide, + :titlefontfamily => :fontfamily_subplot, + :legendfontfamily => :fontfamily_subplot, + :titlefontcolor => :foreground_color_subplot, + :legendfontcolor => :foreground_color_subplot, + :tickfontcolor => :foreground_color_text, + :guidefontcolor => :foreground_color_guide, ) # these can match values from the parent container (axis --> subplot --> plot) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 1ef9a2d7..d6c9c778 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -19,7 +19,10 @@ const _pyplot_attr = merge_with_base_supported([ :title, :title_location, :titlefont, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :legendtitle, :colorbar, :marker_z, :line_z, :fill_z, @@ -128,6 +131,7 @@ end # # anything else just gets a bluesred gradient # py_colormap(c, α=nothing) = py_colormap(default_gradient(), α) +py_color(s) = py_color(parse(Colorant, string(s))) py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c)) py_color(cs::AVec) = map(py_color, cs) py_color(grad::ColorGradient) = py_color(grad.colors) @@ -923,8 +927,8 @@ function py_set_axis_colors(sp, ax, a::Axis) tickcolor = sp[:framestyle] == :zerolines ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis]) ax[:tick_params](axis=string(a[:letter]), which="both", colors=tickcolor, - labelcolor=py_color(a[:foreground_color_text])) - ax[axissym][:label][:set_color](py_color(a[:foreground_color_guide])) + labelcolor=py_color(a[:tickfontcolor])) + ax[axissym][:label][:set_color](py_color(a[:guidefontcolor])) end end @@ -978,9 +982,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) :title end ax[func][:set_text](sp[:title]) - ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefont].pointsize)) - ax[func][:set_family](sp[:titlefont].family) - ax[func][:set_color](py_color(sp[:foreground_color_title])) + ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefontsize])) + ax[func][:set_family](sp[:titlefontfamily]) + ax[func][:set_color](py_color(sp[:titlefontcolor])) # ax[:set_title](sp[:title], loc = loc) end @@ -1005,10 +1009,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) fig = plt.o cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefont].pointsize),family=sp[:yaxis][:guidefont].family) + cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontamily], color = py_color(sp[:yaxis][:guidefontcolor])) for lab in cb[:ax][:yaxis][:get_ticklabels]() - lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfont].pointsize)) - lab[:set_family](sp[:yaxis][:tickfont].family) + lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfontsize])) + lab[:set_family](sp[:yaxis][:tickfontfamily]) + lab[:set_color](py_color(sp[:yaxis][:tickfontcolor])) end sp.attr[:cbar_handle] = cb sp.attr[:cbar_ax] = cbax @@ -1068,11 +1073,11 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() end - pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefont].pointsize)) - pyaxis[:label][:set_family](axis[:guidefont].family) + pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefontsize])) + pyaxis[:label][:set_family](axis[:guidefontfamily]) for lab in ax[Symbol("get_", letter, "ticklabels")]() - lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfont].pointsize)) - lab[:set_family](axis[:tickfont].family) + lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfontsize])) + lab[:set_family](axis[:tickfontfamily]) lab[:set_rotation](axis[:rotation]) end if axis[:grid] && !(ticks in (:none, nothing, false)) @@ -1248,7 +1253,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) labels, loc = get(_pyplot_legend_pos, leg, "best"), scatterpoints = 1, - fontsize = py_dpi_scale(plt, sp[:legendfont].pointsize) + fontsize = py_dpi_scale(plt, sp[:legendfontsize]) # family = sp[:legendfont].family # framealpha = 0.6 ) @@ -1256,8 +1261,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) fgcolor = py_color(sp[:foreground_color_legend]) + lfcolor = py_color(sp[:legendfontcolor]) for txt in leg[:get_texts]() - PyPlot.plt[:setp](txt, color = fgcolor, family = sp[:legendfont].family) + PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily]) end # set some legend properties From 7ec54b9c2e41b555aec6bbe8c41778711b331a46 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 19:54:52 +0100 Subject: [PATCH 484/720] update plotly(js) --- src/backends.jl | 6 +++--- src/backends/plotly.jl | 19 ++++++++++++------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/backends.jl b/src/backends.jl index 1dd5d8ad..94199b00 100644 --- a/src/backends.jl +++ b/src/backends.jl @@ -51,8 +51,8 @@ _series_updated(plt::Plot, series::Series) = nothing _before_layout_calcs(plt::Plot) = nothing -title_padding(sp::Subplot) = sp[:title] == "" ? 0mm : sp[:titlefont].pointsize * pt -guide_padding(axis::Axis) = axis[:guide] == "" ? 0mm : axis[:guidefont].pointsize * pt +title_padding(sp::Subplot) = sp[:title] == "" ? 0mm : sp[:titlefontsize] * pt +guide_padding(axis::Axis) = axis[:guide] == "" ? 0mm : axis[:guidefontsize] * pt "Returns the (width,height) of a text label." function text_size(lablen::Int, sz::Number, rot::Number = 0) @@ -93,7 +93,7 @@ function tick_padding(axis::Axis) # hgt # get the height of the rotated label - text_size(longest_label, axis[:tickfont].pointsize, rot)[2] + text_size(longest_label, axis[:tickfontsize], rot)[2] end end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 3b149a20..e58d685c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -2,7 +2,7 @@ # https://plot.ly/javascript/getting-started @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotly.jl")) end const _plotly_attr = merge_with_base_supported([ @@ -19,7 +19,12 @@ const _plotly_attr = merge_with_base_supported([ :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :markerstrokestyle, :fillrange, :fillcolor, :fillalpha, :bins, - :title, :title_location, :titlefont, + :title, :title_location, + :titlefontfamily, :titlefontsize, :titlefonthalign, :titlefontvalign, + :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, :tickfont, :guidefont, :legendfont, @@ -254,9 +259,9 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:tickangle] = -axis[:rotation] if !(axis[:ticks] in (nothing, :none)) - ax[:titlefont] = plotly_font(axis[:guidefont], axis[:foreground_color_guide]) + ax[:titlefont] = plotly_font(guidefont(axis)) ax[:type] = plotly_scale(axis[:scale]) - ax[:tickfont] = plotly_font(axis[:tickfont], axis[:foreground_color_text]) + ax[:tickfont] = plotly_font(tickfont(axis)) ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) @@ -334,8 +339,8 @@ function plotly_layout(plt::Plot) 0.5 * (left(bb) + right(bb)) end titlex, titley = xy_mm_to_pcts(xmm, top(bbox(sp)), w*px, h*px) - titlefont = font(sp[:titlefont], :top, sp[:foreground_color_title]) - push!(d_out[:annotations], plotly_annotation_dict(titlex, titley, text(sp[:title], titlefont))) + title_font = font(titlefont(sp), :top) + push!(d_out[:annotations], plotly_annotation_dict(titlex, titley, text(sp[:title], title_font))) end d_out[:plot_bgcolor] = rgba_string(sp[:background_color_inside]) @@ -376,7 +381,7 @@ function plotly_layout(plt::Plot) d_out[:legend] = KW( :bgcolor => rgba_string(sp[:background_color_legend]), :bordercolor => rgba_string(sp[:foreground_color_legend]), - :font => plotly_font(sp[:legendfont], sp[:foreground_color_legend]), + :font => plotly_font(legendfont(sp)), :x => xpos, :y => ypos ) From d4f67ec3b573ea70e67efae657b58c95434d6f52 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 20:31:28 +0100 Subject: [PATCH 485/720] update glvisualize --- src/backends/glvisualize.jl | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 924eca72..b0d93511 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -10,7 +10,7 @@ TODO =# @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "glvisualize.jl")) end const _glvisualize_attr = merge_with_base_supported([ @@ -24,10 +24,10 @@ const _glvisualize_attr = merge_with_base_supported([ :markerstrokewidth, :markerstrokecolor, :markerstrokealpha, :fillrange, :fillcolor, :fillalpha, :bins, :bar_width, :bar_edges, :bar_position, - :title, :title_location, :titlefont, + :title, :title_location, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :tickfont, :guidefont, :legendfont, :titlefont, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :colorbar, :marker_z, @@ -612,7 +612,7 @@ function draw_ticks( axis, ticks, isx, isorigin, lims, m, text = "", positions = Point2f0[], offsets=Vec2f0[] ) - sz = pointsize(axis[:tickfont]) + sz = pointsize(tickfont(axis)) atlas = GLVisualize.get_texture_atlas() font = GLVisualize.defaultfont() @@ -745,7 +745,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are :position => map(x-> x[2], ticklabels), :offset => map(last, ticklabels), :color => fcolor, - :relative_scale => pointsize(xaxis[:tickfont]), + :relative_scale => pointsize(tickfont(xaxis)), :scale_primitive => false ) push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) @@ -760,7 +760,7 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are :position => map(x-> x[2], ticklabels), :offset => map(last, ticklabels), :color => fcolor, - :relative_scale => pointsize(xaxis[:tickfont]), + :relative_scale => pointsize(tickfont(xaxis)), :scale_primitive => false ) push!(axis_vis, visualize(map(first, ticklabels), Style(:default), kw_args)) @@ -777,8 +777,8 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are area_w = GeometryTypes.widths(area) if sp[:title] != "" - tf = sp[:titlefont]; color = gl_color(sp[:foreground_color_title]) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, tf.rotation, color) + tf = titlefont(sp) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, tf.rotation, tf.color) xy = Point2f0(area.w/2, area_w[2] + pointsize(tf)/2) kw = Dict(:model => text_model(font, xy), :scale_primitive => true) extract_font(font, kw) @@ -786,9 +786,9 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are push!(axis_vis, glvisualize_text(xy, t, kw)) end if xaxis[:guide] != "" - tf = xaxis[:guidefont]; color = gl_color(xaxis[:foreground_color_guide]) + tf = guidefont(xaxis) xy = Point2f0(area.w/2, - pointsize(tf)/2) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, tf.rotation, color) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :bottom, tf.rotation, tf.color) kw = Dict(:model => text_model(font, xy), :scale_primitive => true) t = PlotText(xaxis[:guide], font) extract_font(font, kw) @@ -796,8 +796,8 @@ function gl_draw_axes_2d(sp::Plots.Subplot{Plots.GLVisualizeBackend}, model, are end if yaxis[:guide] != "" - tf = yaxis[:guidefont]; color = gl_color(yaxis[:foreground_color_guide]) - font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 90f0, color) + tf = guidefont(yaxis) + font = Plots.Font(tf.family, tf.pointsize, :hcenter, :top, 90f0, tf.color) xy = Point2f0(-pointsize(tf)/2, area.h/2) kw = Dict(:model => text_model(font, xy), :scale_primitive=>true) t = PlotText(yaxis[:guide], font) @@ -1483,9 +1483,8 @@ function make_label(sp, series, i) else series[:label] end - color = sp[:foreground_color_legend] - ft = sp[:legendfont] - font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, color) + ft = legendfont(sp) + font = Plots.Font(ft.family, ft.pointsize, :left, :bottom, 0.0, ft.color) xy = Point2f0(w+gap, 0.0) kw = Dict(:model => text_model(font, xy), :scale_primitive=>false) extract_font(font, kw) From 189b2e5cd61a926ca347604bda1d67355456a743 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 20:36:26 +0100 Subject: [PATCH 486/720] update glvisualize --- src/backends/glvisualize.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index b0d93511..f89b8afc 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -27,7 +27,10 @@ const _glvisualize_attr = merge_with_base_supported([ :title, :title_location, :window_title, :guide, :lims, :ticks, :scale, :flip, :rotation, - :tickfont, :guidefont, :legendfont, :titlefont, + :titlefontsize, :titlefontcolor, + :legendfontsize, :legendfontcolor, + :tickfontsize, + :guidefontsize, :guidefontcolor, :grid, :gridalpha, :gridstyle, :gridlinewidth, :legend, :colorbar, :marker_z, From 78f10de8cda80d06ffdadd9a7dbf671f657e2bc5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 20:44:22 +0100 Subject: [PATCH 487/720] update inspectdr --- src/backends/inspectdr.jl | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 7d09045a..3718b2ee 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -14,7 +14,7 @@ Add in functionality to Plots.jl: =# @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "inspectdr.jl")) end # --------------------------------------------------------------------------- @@ -32,10 +32,13 @@ const _inspectdr_attr = merge_with_base_supported([ :markerstrokestyle, #Causes warning not to have it... what is this? :fillcolor, :fillalpha, #:fillrange, # :bins, :bar_width, :bar_edges, :bar_position, - :title, :title_location, :titlefont, + :title, :title_location, :window_title, :guide, :lims, :scale, #:ticks, :flip, :rotation, - :tickfont, :guidefont, :legendfont, + :titlefontfamily, :titlefontsize, :titlefontcolor, + :legendfontfamily, :legendfontsize, :legendfontcolor, + :tickfontfamily, :tickfontsize, :tickfontcolor, + :guidefontfamily, :guidefontsize, :guidefontcolor, :grid, :legend, #:colorbar, # :marker_z, # :line_z, @@ -373,24 +376,24 @@ function _inspectdr_setupsubplot(sp::Subplot{InspectDRBackend}) l[:frame_canvas].fillcolor = _inspectdr_mapcolor(sp[:background_color_subplot]) l[:frame_data].fillcolor = _inspectdr_mapcolor(sp[:background_color_inside]) l[:frame_data].line.color = _inspectdr_mapcolor(xaxis[:foreground_color_axis]) - l[:font_title] = InspectDR.Font(sp[:titlefont].family, - _inspectdr_mapptsize(sp[:titlefont].pointsize), - color = _inspectdr_mapcolor(sp[:foreground_color_title]) + l[:font_title] = InspectDR.Font(sp[:titlefontfamily], + _inspectdr_mapptsize(sp[:titlefontsize]), + color = _inspectdr_mapcolor(sp[:titlefontcolor]) ) #Cannot independently control fonts of axes with InspectDR: - l[:font_axislabel] = InspectDR.Font(xaxis[:guidefont].family, - _inspectdr_mapptsize(xaxis[:guidefont].pointsize), - color = _inspectdr_mapcolor(xaxis[:foreground_color_guide]) + l[:font_axislabel] = InspectDR.Font(xaxis[:guidefontfamily], + _inspectdr_mapptsize(xaxis[:guidefontsize]), + color = _inspectdr_mapcolor(xaxis[:guidefontcolor]) ) - l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfont].family, - _inspectdr_mapptsize(xaxis[:tickfont].pointsize), - color = _inspectdr_mapcolor(xaxis[:foreground_color_text]) + l[:font_ticklabel] = InspectDR.Font(xaxis[:tickfontfamily], + _inspectdr_mapptsize(xaxis[:tickfontsize]), + color = _inspectdr_mapcolor(xaxis[:tickfontcolor]) ) l[:enable_legend] = (sp[:legend] != :none) #l[:halloc_legend] = 150 #TODO: compute??? - l[:font_legend] = InspectDR.Font(sp[:legendfont].family, - _inspectdr_mapptsize(sp[:legendfont].pointsize), - color = _inspectdr_mapcolor(sp[:foreground_color_legend]) + l[:font_legend] = InspectDR.Font(sp[:legendfontfamily], + _inspectdr_mapptsize(sp[:legendfontsize]), + color = _inspectdr_mapcolor(sp[:legendfontcolor]) ) l[:frame_legend].fillcolor = _inspectdr_mapcolor(sp[:background_color_legend]) end From 129a91b36fcc2e3cef70b8e8bf7a726481838f17 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 19 Nov 2017 21:18:04 +0100 Subject: [PATCH 488/720] update arg description --- src/arg_desc.jl | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index f0df3e92..386639b6 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -66,11 +66,17 @@ const _arg_desc = KW( :dpi => "Number. Dots Per Inch of output figures", :display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.", :extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.", +:fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides", # subplot args :title => "String. Subplot title.", :title_location => "Symbol. Position of subplot title. Values: `:left`, `:center`, `:right`", -:titlefont => "Font. Font of subplot title.", +:titlefontfamily => "String or Symbol. Font family of subplot title.", +:titlefontsize => "Integer. Font pointsize of subplot title.", +:titlefonthalign => "Symbol. Font horizontal alignment of subplot title: :hcenter, :left, :right or :center", +:titlefontvalign => "Symbol. Font vertical alignment of subplot title: :vcenter, :top, :bottom or :center", +:titlefontrotation => "Real. Font rotation of subplot title", +:titlefontcolor => "Color Type. Font color of subplot title", :background_color_subplot => "Color Type or `:match` (matches `:background_color`). Base background color of the subplot.", :background_color_legend => "Color Type or `:match` (matches `:background_color_subplot`). Background color of the legend.", :background_color_inside => "Color Type or `:match` (matches `:background_color_subplot`). Background color inside the plot area (under the grid).", @@ -79,7 +85,12 @@ const _arg_desc = KW( :foreground_color_title => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of subplot title.", :color_palette => "Vector of colors (cycle through) or color gradient (generate list from gradient) or `:auto` (generate a color list using `Colors.distiguishable_colors` and custom seed colors chosen to contrast with the background). The color palette is a color list from which series colors are automatically chosen.", :legend => "Bool (show the legend?) or Symbol (legend position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:inside`, `:legend`, `:topright`, `:topleft`, `:bottomleft`, `:bottomright` (note: only some may be supported in each backend)", -:legendtitle => "String or nothing (default). Sets the legend title.", +:legendfontfamily => "String or Symbol. Font family of legend entries.", +:legendfontsize => "Integer. Font pointsize of legend entries.", +:legendfonthalign => "Symbol. Font horizontal alignment of legend entries: :hcenter, :left, :right or :center", +:legendfontvalign => "Symbol. Font vertical alignment of legend entries: :vcenter, :top, :bottom or :center", +:legendfontrotation => "Real. Font rotation of legend entries", +:legendfontcolor => "Color Type. Font color of legend entries", :colorbar => "Bool (show the colorbar?) or Symbol (colorbar position). Symbol values: `:none`, `:best`, `:right`, `:left`, `:top`, `:bottom`, `:legend` (matches legend value) (note: only some may be supported in each backend)", :clims => "`:auto` or NTuple{2,Number}. Fixes the limits of the colorbar.", :legendfont => "Font. Font of legend items.", @@ -104,8 +115,18 @@ const _arg_desc = KW( :rotation => "Number. Degrees rotation of tick labels.", :flip => "Bool. Should we flip (reverse) the axis?", :formatter => "Function, :scientific, or :auto. A method which converts a number to a string for tick labeling.", -:tickfont => "Font. Font of axis tick labels.", -:guidefont => "Font. Font of axis guide (label).", +:tickfontfamily => "String or Symbol. Font family of tick labels.", +:tickfontsize => "Integer. Font pointsize of tick labels.", +:tickfonthalign => "Symbol. Font horizontal alignment of tick labels: :hcenter, :left, :right or :center", +:tickfontvalign => "Symbol. Font vertical alignment of tick labels: :vcenter, :top, :bottom or :center", +:tickfontrotation => "Real. Font rotation of tick labels", +:tickfontcolor => "Color Type. Font color of tick labels", +:guidefontfamily => "String or Symbol. Font family of axes guides.", +:guidefontsize => "Integer. Font pointsize of axes guides.", +:guidefonthalign => "Symbol. Font horizontal alignment of axes guides: :hcenter, :left, :right or :center", +:guidefontvalign => "Symbol. Font vertical alignment of axes guides: :vcenter, :top, :bottom or :center", +:guidefontrotation => "Real. Font rotation of axes guides", +:guidefontcolor => "Color Type. Font color of axes guides", :foreground_color_axis => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of axis ticks.", :foreground_color_border => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of plot area border (spines).", :foreground_color_text => "Color Type or `:match` (matches `:foreground_color_subplot`). Color of tick labels.", From f7765c80b84d96c8de1ce68a7888f9de311e85e6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 20 Nov 2017 16:54:05 +0100 Subject: [PATCH 489/720] fix guidefontamily typo in pyplot --- 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 d6c9c778..81bc5a94 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1009,7 +1009,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) fig = plt.o cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontamily], color = py_color(sp[:yaxis][:guidefontcolor])) + cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor])) for lab in cb[:ax][:yaxis][:get_ticklabels]() lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfontsize])) lab[:set_family](sp[:yaxis][:tickfontfamily]) From dbf96a69d78f47a9f38b63ec8c29c141cbea003f Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Tue, 21 Nov 2017 13:58:03 +0100 Subject: [PATCH 490/720] gr: fix 'hidden window' problem after savefig --- src/backends/gr.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 7261ca2c..2a10ad02 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1329,12 +1329,18 @@ for (mime, fmt) in _gr_mimeformats @eval function _show(io::IO, ::MIME{Symbol($mime)}, plt::Plot{GRBackend}) GR.emergencyclosegks() filepath = tempname() * "." * $fmt + env = get(ENV, "GKSwstype", "0") ENV["GKSwstype"] = $fmt ENV["GKS_FILEPATH"] = filepath gr_display(plt) GR.emergencyclosegks() write(io, readstring(filepath)) rm(filepath) + if env != "0" + ENV["GKSwstype"] = env + else + pop!(ENV,"GKSwstype") + end end end From 6d4717fc96f59af7ebebf2a5c208ee1c188b3ce4 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 22 Nov 2017 21:26:53 +0100 Subject: [PATCH 491/720] gr: added support for non-string legend labels --- src/backends/gr.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 2a10ad02..912ad1d1 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1212,7 +1212,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) else lab = series[:label] end - tbx, tby = gr_inqtext(0, 0, lab) + tbx, tby = gr_inqtext(0, 0, string(lab)) w = max(w, tbx[3] - tbx[1]) end if w > 0 @@ -1271,7 +1271,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end GR.settextalign(GR.TEXT_HALIGN_LEFT, GR.TEXT_VALIGN_HALF) gr_set_textcolor(sp[:legendfontcolor]) - gr_text(xpos, ypos, lab) + gr_text(xpos, ypos, string(lab)) ypos -= dy end end From 714f8dea1dcce2c4c02ee4052f27cf56e295e337 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 30 Nov 2017 09:45:09 +0100 Subject: [PATCH 492/720] fix axes limits for fill=true in 3d plots --- src/axes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/axes.jl b/src/axes.jl index d4fac7cb..a31e7228 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -355,7 +355,7 @@ function expand_extrema!(sp::Subplot, d::KW) if fr == nothing && d[:seriestype] == :bar fr = 0.0 end - if fr != nothing + if fr != nothing && !all3D(d) axis = sp.attr[vert ? :yaxis : :xaxis] if typeof(fr) <: Tuple for fri in fr From 4c55ff5df846b402eebdec7f4514d47611f7fc49 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 30 Nov 2017 11:01:12 +0100 Subject: [PATCH 493/720] use new StatPlots df syntax in testexamples --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index b3ac5f6b..ac9a3d62 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -252,7 +252,7 @@ PlotExample("DataFrames", [:(begin import RDatasets iris = RDatasets.dataset("datasets", "iris") - scatter(iris, :SepalLength, :SepalWidth, group=:Species, + @df iris scatter(:SepalLength, :SepalWidth, group=:Species, title = "My awesome plot", xlabel = "Length", ylabel = "Width", marker = (0.5, [:cross :hex :star7], 12), bg=RGB(.2,.2,.2)) end)] From 49eb2c426d11d24d1a37822f9d2f1a3a6d105f72 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 30 Nov 2017 11:05:05 +0100 Subject: [PATCH 494/720] update testexample 30 --- src/examples.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index ac9a3d62..481db2a9 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -301,8 +301,8 @@ PlotExample("Boxplot and Violin series recipes", [:(begin import RDatasets singers = RDatasets.dataset("lattice", "singer") - violin(singers, :VoicePart, :Height, line = 0, fill = (0.2, :blue)) - boxplot!(singers, :VoicePart, :Height, line = (2,:black), fill = (0.3, :orange)) + @df singers violin(:VoicePart, :Height, line = 0, fill = (0.2, :blue)) + @df singers boxplot!(:VoicePart, :Height, line = (2,:black), fill = (0.3, :orange)) end)] ), From dd16c7d560ad5127bda2a726bbd92f1afa762eab Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 30 Nov 2017 11:47:20 +0100 Subject: [PATCH 495/720] extend grid lines to axes limits --- src/axes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index d4fac7cb..ccb3611d 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -577,7 +577,7 @@ function axis_drawing_info(sp::Subplot) push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick end # sp[:draw_axes_border] && push!(xaxis_segs, (xtick, ymax), (xtick, t2)) # top tick - xaxis[:grid] && push!(xgrid_segs, (xtick, t1), (xtick, t2)) # vertical grid + xaxis[:grid] && push!(xgrid_segs, (xtick, ymin), (xtick, ymax)) # vertical grid end end @@ -616,7 +616,7 @@ function axis_drawing_info(sp::Subplot) push!(ytick_segs, (tick_start, ytick), (tick_stop, ytick)) # left tick end # sp[:draw_axes_border] && push!(yaxis_segs, (xmax, ytick), (t2, ytick)) # right tick - yaxis[:grid] && push!(ygrid_segs, (t1, ytick), (t2, ytick)) # horizontal grid + yaxis[:grid] && push!(ygrid_segs, (xmin, ytick), (xmax, ytick)) # horizontal grid end end end From a7fcf77251af7100edd027d7b02106652471f847 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 30 Nov 2017 16:26:48 +0100 Subject: [PATCH 496/720] allow to change the foreground_color_legend in gr --- src/backends/gr.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 912ad1d1..1530d19e 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1222,8 +1222,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setfillintstyle(GR.INTSTYLE_SOLID) gr_set_fillcolor(sp[:background_color_legend]) GR.fillrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n) - GR.setlinetype(1) - GR.setlinewidth(1) + gr_set_line(1, :solid, sp[:foreground_color_legend]) GR.drawrect(xpos - 0.08, xpos + w + 0.02, ypos + dy, ypos - dy * n) i = 0 if sp[:legendtitle] != nothing From 28c958fb2032523181c8396a9afc3f4d1d689d6a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 1 Dec 2017 16:14:59 +0100 Subject: [PATCH 497/720] set tick marks color to grid color for framestyle = :grid --- 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 81bc5a94..8a9c7680 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -924,7 +924,7 @@ function py_set_axis_colors(sp, ax, a::Axis) end axissym = Symbol(a[:letter], :axis) if haskey(ax, axissym) - tickcolor = sp[:framestyle] == :zerolines ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis]) + tickcolor = sp[:framestyle] in (:zerolines, :grid) ? py_color(plot_color(a[:foreground_color_grid], a[:gridalpha])) : py_color(a[:foreground_color_axis]) ax[:tick_params](axis=string(a[:letter]), which="both", colors=tickcolor, labelcolor=py_color(a[:tickfontcolor])) From 899afd625a41bc93dfdc22bc4e45635a927dfcd0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 4 Dec 2017 09:16:00 +0100 Subject: [PATCH 498/720] add new heme() function --- src/themes.jl | 78 +++++++++++++++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 34 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 840078dd..0f09246f 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -4,43 +4,53 @@ Specify the colour theme for plots. """ function theme(s::Symbol; kw...) - # reset? - if s == :none || s == :default - PlotUtils.clibrary(:Plots) - PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) - default(; - bg = :white, - bglegend = :match, - bginside = :match, - bgoutside = :match, - fg = :auto, - fglegend = :match, - fggrid = :match, - fgaxis = :match, - fgtext = :match, - fgborder = :match, - fgguide = :match, - palette = :auto - ) - return - end - - # update the default gradient and other defaults - thm = PlotThemes._themes[s] - if thm.gradient != nothing + defaults = merge(_initial_defaults..., s.defaults, kw) + if haskey(s.defaults, :gradient) PlotUtils.clibrary(:misc) PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) end - default(; - bg = thm.bg_secondary, - bginside = thm.bg_primary, - fg = thm.lines, - fgtext = thm.text, - fgguide = thm.text, - fglegend = thm.text, - palette = thm.palette, - kw... - ) + default(; defaults...) + return end +# function theme(s::Symbol; kw...) +# # reset? +# if s == :none || s == :default +# PlotUtils.clibrary(:Plots) +# PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) +# default(; +# bg = :white, +# bglegend = :match, +# bginside = :match, +# bgoutside = :match, +# fg = :auto, +# fglegend = :match, +# fggrid = :match, +# fgaxis = :match, +# fgtext = :match, +# fgborder = :match, +# fgguide = :match, +# palette = :auto +# ) +# return +# end +# +# # update the default gradient and other defaults +# thm = PlotThemes._themes[s] +# if thm.gradient != nothing +# PlotUtils.clibrary(:misc) +# PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) +# end +# default(; +# bg = thm.bg_secondary, +# bginside = thm.bg_primary, +# fg = thm.lines, +# fgtext = thm.text, +# fgguide = thm.text, +# fglegend = thm.text, +# palette = thm.palette, +# kw... +# ) +# end + @deprecate set_theme(s) theme(s) From e02a70249eba3763fcd924651cd7a45d0f761b2a Mon Sep 17 00:00:00 2001 From: JackDevine Date: Mon, 4 Dec 2017 22:34:45 +1300 Subject: [PATCH 499/720] Examples are limited to 90 columns. Thanks @daschw for pointing out the correct place to make these changes. I have also changed the explanation texts, which may be a little overkill, but I do think that the style guides apply to Markdown string too (could be wrong though). --- src/examples.jl | 182 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 124 insertions(+), 58 deletions(-) diff --git a/src/examples.jl b/src/examples.jl index fabb368d..386d45d9 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -18,7 +18,14 @@ PlotExample("Lines", ), PlotExample("Functions, adding data, and animations", - "Plot multiple functions. You can also put the function first, or use the form `plot(f, xmin, xmax)` where f is a Function or AbstractVector{Function}.\n\nGet series data: `x, y = plt[i]`. Set series data: `plt[i] = (x,y)`. Add to the series with `push!`/`append!`.\n\nEasily build animations. (`convert` or `ffmpeg` must be available to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the animation.", +""" +Plot multiple functions. You can also put the function first, or use the form `plot(f, +xmin, xmax)` where f is a Function or AbstractVector{Function}.\n\nGet series data: +`x, y = plt[i]`. Set series data: `plt[i] = (x,y)`. Add to the series with +`push!`/`append!`.\n\nEasily build animations. (`convert` or `ffmpeg` must be available +to generate the animation.) Use command `gif(anim, filename, fps=15)` to save the +animation. +""", [:(begin p = plot([sin,cos], zeros(0), leg=false) anim = Animation() @@ -37,23 +44,35 @@ PlotExample("Parametric plots", ), PlotExample("Colors", - "Access predefined palettes (or build your own with the `colorscheme` method). Line/marker colors are auto-generated from the plot's palette, unless overridden. Set the `z` argument to turn on series gradients.", +""" +Access predefined palettes (or build your own with the `colorscheme` method). +Line/marker colors are auto-generated from the plot's palette, unless overridden. Set +the `z` argument to turn on series gradients. +""", [:(begin - y = rand(100) - plot(0:10:100,rand(11,4),lab="lines",w=3,palette=:grays,fill=0, α=0.6) - scatter!(y, zcolor=abs.(y-.5), m=(:heat,0.8,stroke(1,:green)), ms=10*abs.(y-0.5)+4, lab="grad") +y = rand(100) +plot(0:10:100,rand(11,4),lab="lines",w=3,palette=:grays,fill=0, α=0.6) +scatter!(y, zcolor=abs.(y-.5), m=(:heat,0.8,stroke(1,:green)), ms=10*abs.(y-0.5)+4, + lab="grad") end)] ), PlotExample("Global", - "Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow you to pass a tuple or value which will be mapped to the relevant args automatically. The `xaxis` below will be replaced with `xlabel` and `xlims` args automatically during the preprocessing step. You can also use shorthand functions: `title!`, `xaxis!`, `yaxis!`, `xlabel!`, `ylabel!`, `xlims!`, `ylims!`, `xticks!`, `yticks!`", +""" +Change the guides/background/limits/ticks. Convenience args `xaxis` and `yaxis` allow +you to pass a tuple or value which will be mapped to the relevant args automatically. +The `xaxis` below will be replaced with `xlabel` and `xlims` args automatically during +the preprocessing step. You can also use shorthand functions: `title!`, `xaxis!`, +`yaxis!`, `xlabel!`, `ylabel!`, `xlims!`, `ylims!`, `xticks!`, `yticks!` +""", [:(begin - y = rand(20,3) - plot(y, xaxis=("XLABEL",(-5,30),0:2:20,:flip), background_color = RGB(0.2,0.2,0.2), leg=false) - hline!(mean(y,1)+rand(1,3), line=(4,:dash,0.6,[:lightgreen :green :darkgreen])) - vline!([5,10]) - title!("TITLE") - yaxis!("YLABEL", :log10) +y = rand(20,3) +plot(y, xaxis=("XLABEL",(-5,30),0:2:20,:flip), background_color = RGB(0.2,0.2,0.2), + leg=false) +hline!(mean(y,1)+rand(1,3), line=(4,:dash,0.6,[:lightgreen :green :darkgreen])) +vline!([5,10]) +title!("TITLE") +yaxis!("YLABEL", :log10) end)] ), @@ -73,7 +92,14 @@ PlotExample("Images", ), PlotExample("Arguments", - "Plot multiple series with different numbers of points. Mix arguments that apply to all series (marker/markersize) with arguments unique to each series (colors). Special arguments `line`, `marker`, and `fill` will automatically figure out what arguments to set (for example, we are setting the `linestyle`, `linewidth`, and `color` arguments with `line`.) Note that we pass a matrix of colors, and this applies the colors to each series.", +""" +Plot multiple series with different numbers of points. Mix arguments that apply to all +series (marker/markersize) with arguments unique to each series (colors). Special +arguments `line`, `marker`, and `fill` will automatically figure out what arguments to +set (for example, we are setting the `linestyle`, `linewidth`, and `color` arguments with +`line`.) Note that we pass a matrix of colors, and this applies the colors to each +series. +""", [:(begin ys = Vector[rand(10), rand(20)] plot(ys, color=[:black :orange], line=(:dot,4), marker=([:hex :d],12,0.8,stroke(3,:gray))) @@ -115,12 +141,13 @@ PlotExample("Line types", PlotExample("Line styles", "", [:(begin - styles = filter(s -> s in Plots.supported_styles(), [:solid, :dash, :dot, :dashdot, :dashdotdot]) - styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors - n = length(styles) - y = cumsum(randn(20,n),1) - plot(y, line = (5, styles), label = map(string,styles), legendtitle = "linestyle") - end)] +styles = filter(s -> s in Plots.supported_styles(), + [:solid, :dash, :dot, :dashdot, :dashdotdot]) +styles = reshape(styles, 1, length(styles)) # Julia 0.6 unfortunately gives an error when transposing symbol vectors +n = length(styles) +y = cumsum(randn(20,n),1) +plot(y, line = (5, styles), label = map(string,styles), legendtitle = "linestyle") + end)] ), PlotExample("Marker types", @@ -150,19 +177,25 @@ PlotExample("Histogram", ), PlotExample("Subplots", - """ - Use the `layout` keyword, and optionally the convenient `@layout` macro to generate arbitrarily complex subplot layouts. - """, +""" +Use the `layout` keyword, and optionally the convenient `@layout` macro to generate +arbitrarily complex subplot layouts. +""", [:(begin - l = @layout([a{0.1h}; b [c;d e]]) - plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, ticks=nothing, border=:none) +l = @layout([a{0.1h}; b [c;d e]]) +plot(randn(100,5), layout=l, t=[:line :histogram :scatter :steppre :bar], leg=false, + ticks=nothing, border=:none) end)] ), PlotExample("Adding to subplots", - "Note here the automatic grid layout, as well as the order in which new series are added to the plots.", +""" +Note here the automatic grid layout, as well as the order in which new series are added +to the plots. +""", [:(begin - plot(Plots.fakedata(100,10), layout=4, palette=[:grays :blues :heat :lightrainbow], bg_inside=[:orange :pink :darkblue :black]) +plot(Plots.fakedata(100,10), layout=4, palette=[:grays :blues :heat :lightrainbow], + bg_inside=[:orange :pink :darkblue :black]) end)] ), @@ -175,43 +208,63 @@ PlotExample("", ), PlotExample("Open/High/Low/Close", - "Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y` argument. This uses recipes to first convert the tuples to OHLC objects, and subsequently create a :path series with the appropriate line segments.", +""" +Create an OHLC chart. Pass in a list of (open,high,low,close) tuples as your `y` +argument. This uses recipes to first convert the tuples to OHLC objects, and +subsequently create a :path series with the appropriate line segments. +""", [:(begin - n=20 - hgt=rand(n)+1 - bot=randn(n) - openpct=rand(n) - closepct=rand(n) - y = OHLC[(openpct[i]*hgt[i]+bot[i], bot[i]+hgt[i], bot[i], closepct[i]*hgt[i]+bot[i]) for i in 1:n] - ohlc(y) +n=20 +hgt=rand(n)+1 +bot=randn(n) +openpct=rand(n) +closepct=rand(n) +y = OHLC[(openpct[i]*hgt[i]+bot[i], bot[i]+hgt[i], bot[i], + closepct[i]*hgt[i]+bot[i]) for i in 1:n] +ohlc(y) end)] ), PlotExample("Annotations", - "The `annotations` keyword is used for text annotations in data-coordinates. Pass in a tuple (x,y,text) or a vector of annotations. `annotate!(ann)` is shorthand for `plot!(; annotation=ann)`. Series annotations are used for annotating individual data points. They require only the annotation... x/y values are computed. A `PlotText` object can be build with the method `text(string, attr...)`, which wraps font and color attributes.", +""" +The `annotations` keyword is used for text annotations in data-coordinates. Pass in a +tuple (x,y,text) or a vector of annotations. `annotate!(ann)` is shorthand for `plot!(; +annotation=ann)`. Series annotations are used for annotating individual data points. +They require only the annotation... x/y values are computed. A `PlotText` object can be +build with the method `text(string, attr...)`, which wraps font and color attributes. +""", [:(begin - y = rand(10) - plot(y, annotations = (3,y[3],text("this is #3",:left)), leg=false) - annotate!([(5, y[5], text("this is #5",16,:red,:center)), (10, y[10], text("this is #10",:right,20,"courier"))]) - scatter!(linspace(2,8,6), rand(6), marker=(50,0.2,:orange), series_annotations = ["series","annotations","map","to","series",text("data",:green)]) +y = rand(10) +plot(y, annotations = (3,y[3],text("this is #3",:left)), leg=false) +annotate!([(5, y[5], text("this is #5",16,:red,:center)), + (10, y[10], text("this is #10",:right,20,"courier"))]) +scatter!(linspace(2,8,6), rand(6), marker=(50,0.2,:orange), + series_annotations = ["series","annotations","map","to","series", + text("data",:green)]) end)] ), PlotExample("Custom Markers", - "A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and the size is expected to be rougly the area of the unit circle.", +"""A `Plots.Shape` is a light wrapper around vertices of a polygon. For supported +backends, pass arbitrary polygons as the marker shapes. Note: The center is (0,0) and +the size is expected to be rougly the area of the unit circle. +""", [:(begin - verts = [(-1.0,1.0),(-1.28,0.6),(-0.2,-1.4),(0.2,-1.4),(1.28,0.6),(1.0,1.0), - (-1.0,1.0),(-0.2,-0.6),(0.0,-0.2),(-0.4,0.6),(1.28,0.6),(0.2,-1.4), - (-0.2,-1.4),(0.6,0.2),(-0.2,0.2),(0.0,-0.2),(0.2,0.2),(-0.2,-0.6)] - x = 0.1:0.2:0.9 - y = 0.7rand(5)+0.15 - plot(x, y, line = (3,:dash,:lightblue), marker = (Shape(verts),30,RGBA(0,0,0,0.2)), - bg=:pink, fg=:darkblue, xlim = (0,1), ylim=(0,1), leg=false) +verts = [(-1.0,1.0),(-1.28,0.6),(-0.2,-1.4),(0.2,-1.4),(1.28,0.6),(1.0,1.0), + (-1.0,1.0),(-0.2,-0.6),(0.0,-0.2),(-0.4,0.6),(1.28,0.6),(0.2,-1.4), + (-0.2,-1.4),(0.6,0.2),(-0.2,0.2),(0.0,-0.2),(0.2,0.2),(-0.2,-0.6)] +x = 0.1:0.2:0.9 +y = 0.7rand(5)+0.15 +plot(x, y, line = (3,:dash,:lightblue), marker = (Shape(verts),30,RGBA(0,0,0,0.2)), + bg=:pink, fg=:darkblue, xlim = (0,1), ylim=(0,1), leg=false) end)] ), PlotExample("Contours", - "Any value for fill works here. We first build a filled contour from a function, then an unfilled contour from a matrix.", +""" +Any value for fill works here. We first build a filled contour from a function, then an +unfilled contour from a matrix. +""", [:(begin x = 1:0.5:20 y = 1:0.5:10 @@ -261,8 +314,9 @@ PlotExample("DataFrames", PlotExample("Groups and Subplots", "", [:(begin - group = rand(map(i->"group $i",1:4),100) - plot(rand(100), layout=@layout([a b;c]), group=group, linetype=[:bar :scatter :steppre]) +group = rand(map(i->"group $i",1:4),100) +plot(rand(100), layout=@layout([a b;c]), group=group, + linetype=[:bar :scatter :steppre]) end)] ), @@ -322,16 +376,24 @@ PlotExample("Animation with subplots", ), PlotExample("Spy", - "For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. As always, the marker shape and size can be changed with `spy(mat, markersize = 3, markershape = :star)`.", +""" +For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` +has various different nonzero values, a colorbar is added. The colorbar can be disabled +with `legend = nothing`. As always, the marker shape and size can be changed with +`spy(mat, markersize = 3, markershape = :star)`. +""", [:(begin - a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) - b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) - plot(spy(a, markershape = :dtriangle), spy(b), markersize = 3, title = ["Unique nonzeros" "Different nonzeros"]) +a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) +b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) +plot(spy(a, markershape = :dtriangle), spy(b), markersize = 3, + title = ["Unique nonzeros" "Different nonzeros"]) end)] ), PlotExample("Magic grid argument", - "The grid lines can be modified individually for each axis with the magic `grid` argument.", +""" +The grid lines can be modified individually for each axis with the magic `grid` argument. +""", [:(begin x = rand(10) p1 = plot(x, title = "Default looks") @@ -343,10 +405,14 @@ PlotExample("Magic grid argument", ), PlotExample("Framestyle", - "The style of the frame/axes of a (sub)plot can be changed with the `framestyle` attribute. The default framestyle is `:axes`.", +""" +The style of the frame/axes of a (sub)plot can be changed with the `framestyle` +attribute. The default framestyle is `:axes`. +""", [:(begin - histogram(fill(randn(1000), 5), framestyle = [:box :semi :axes :grid :none], - title = [":box" ":semi" ":axes" ":grid" ":none"], color = RowVector(1:5), layout = 5, label = "") +histogram(fill(randn(1000), 5), framestyle = [:box :semi :axes :grid :none], + title = [":box" ":semi" ":axes" ":grid" ":none"], + color = RowVector(1:5), layout = 5, label = "") end)] ), From b987331b4fc5793fb6bb0794f645779528d989ad Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 4 Dec 2017 14:54:35 +0100 Subject: [PATCH 500/720] update new heme() function --- src/args.jl | 6 ++++- src/themes.jl | 68 +++++++++++++++++++-------------------------------- 2 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/args.jl b/src/args.jl index 70fa458c..b9c8f2a0 100644 --- a/src/args.jl +++ b/src/args.jl @@ -417,6 +417,7 @@ const _all_defaults = KW[ ] const _initial_defaults = deepcopy(_all_defaults) +const _initial_axis_defaults = deepcopy(_axis_defaults) # to be able to reset font sizes to initial values const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefontsize], @@ -614,7 +615,10 @@ function default(d::KW, k::Symbol) get(d, k, default(k)) end -reset_defaults() = foreach(merge!, _all_defaults, _initial_defaults) +function reset_defaults() + foreach(merge!, _all_defaults, _initial_defaults) + merge!(_axis_defaults, _initial_axis_defaults) +end # ----------------------------------------------------------------------------- diff --git a/src/themes.jl b/src/themes.jl index 0f09246f..b570836f 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -4,53 +4,35 @@ Specify the colour theme for plots. """ function theme(s::Symbol; kw...) - defaults = merge(_initial_defaults..., s.defaults, kw) - if haskey(s.defaults, :gradient) + # Reset to defaults to overwrite active team + reset_defaults() + thm = PlotThemes._themes[s] + + # Set the theme's gradient as default + if haskey(thm.defaults, :gradient) PlotUtils.clibrary(:misc) PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) + else + PlotUtils.clibrary(:Plots) + PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) end - default(; defaults...) + + # maybe overwrite the theme's gradient + kw = KW(kw) + if haskey(kw, :gradient) + kwgrad = pop!(kw, :gradient) + for clib in clibraries() + if kwgrad in cgradients(clib) + PlotUtils.clibrary(clib) + PlotUtils.default_cgrad(default = :sequential, sequential = kwgrad) + break + end + end + end + + # Set the theme's defaults + default(; thm.defaults..., kw...) return end -# function theme(s::Symbol; kw...) -# # reset? -# if s == :none || s == :default -# PlotUtils.clibrary(:Plots) -# PlotUtils.default_cgrad(default = :sequential, sequential = :inferno) -# default(; -# bg = :white, -# bglegend = :match, -# bginside = :match, -# bgoutside = :match, -# fg = :auto, -# fglegend = :match, -# fggrid = :match, -# fgaxis = :match, -# fgtext = :match, -# fgborder = :match, -# fgguide = :match, -# palette = :auto -# ) -# return -# end -# -# # update the default gradient and other defaults -# thm = PlotThemes._themes[s] -# if thm.gradient != nothing -# PlotUtils.clibrary(:misc) -# PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) -# end -# default(; -# bg = thm.bg_secondary, -# bginside = thm.bg_primary, -# fg = thm.lines, -# fgtext = thm.text, -# fgguide = thm.text, -# fglegend = thm.text, -# palette = thm.palette, -# kw... -# ) -# end - @deprecate set_theme(s) theme(s) From 22d8ecffe5268e0d645bf11be8f4a8fc782292aa Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 4 Dec 2017 15:53:45 +0100 Subject: [PATCH 501/720] fix typo --- src/themes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes.jl b/src/themes.jl index b570836f..40a9e1f8 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -4,7 +4,7 @@ Specify the colour theme for plots. """ function theme(s::Symbol; kw...) - # Reset to defaults to overwrite active team + # Reset to defaults to overwrite active theme reset_defaults() thm = PlotThemes._themes[s] From 2cf365d36de7ef60b9b1c2ace63c2d2e7db3032c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 4 Dec 2017 19:34:02 +0100 Subject: [PATCH 502/720] Allow magic arguments in default() --- src/args.jl | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/args.jl b/src/args.jl index 70fa458c..1e7affed 100644 --- a/src/args.jl +++ b/src/args.jl @@ -367,6 +367,18 @@ const _axis_defaults = KW( :showaxis => true, ) +const _magic_arguments = [ + :axis, + :grid, + :marker, + :line, + :fill, + :titlefont, + :legendfont, + :guidefont, + :tickfont, +] + const _suppress_warnings = Set{Symbol}([ :x_discrete_indices, :y_discrete_indices, @@ -379,6 +391,7 @@ const _suppress_warnings = Set{Symbol}([ :primary, :smooth, :relative_bbox, + _magic_arguments... ]) # add defaults for the letter versions @@ -605,6 +618,8 @@ function default(k::Symbol, v) end function default(; kw...) + kw = KW(kw) + preprocessArgs!(kw) for (k,v) in kw default(k, v) end From 81ef4bdee80f3bf3a337bc5aa36b562289862617 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 4 Dec 2017 19:45:21 +0100 Subject: [PATCH 503/720] remove _magic_arguments --- src/args.jl | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/args.jl b/src/args.jl index 1e7affed..15734286 100644 --- a/src/args.jl +++ b/src/args.jl @@ -367,18 +367,6 @@ const _axis_defaults = KW( :showaxis => true, ) -const _magic_arguments = [ - :axis, - :grid, - :marker, - :line, - :fill, - :titlefont, - :legendfont, - :guidefont, - :tickfont, -] - const _suppress_warnings = Set{Symbol}([ :x_discrete_indices, :y_discrete_indices, @@ -391,7 +379,6 @@ const _suppress_warnings = Set{Symbol}([ :primary, :smooth, :relative_bbox, - _magic_arguments... ]) # add defaults for the letter versions From 5d0adb178387f8e199713be469fdc702c7639c4f Mon Sep 17 00:00:00 2001 From: JackDevine Date: Tue, 5 Dec 2017 08:36:04 +1300 Subject: [PATCH 504/720] Add comma --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index 27bf7d32..e43fa6fe 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -380,7 +380,7 @@ PlotExample("Spy", For a matrix `mat` with unique nonzeros `spy(mat)` returns a colorless plot. If `mat` has various different nonzero values, a colorbar is added. The colorbar can be disabled with `legend = nothing`. -""" +""", [:(begin a = spdiagm((ones(50), ones(49), ones(49), ones(40), ones(40)),(0, 1, -1, 10, -10)) b = spdiagm((1:50, 1:49, 1:49, 1:40, 1:40),(0, 1, -1, 10, -10)) From 39a7815f8004ae431dd1d2f9dacdd25ae88ca968 Mon Sep 17 00:00:00 2001 From: Hayato Ikoma Date: Tue, 5 Dec 2017 08:54:54 -0800 Subject: [PATCH 505/720] Fix the display of an grayscale image for image-nonsupported backends --- src/series.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index 1f00bb6e..a5425e94 100644 --- a/src/series.jl +++ b/src/series.jl @@ -306,9 +306,9 @@ end # # images - grays @recipe function f(mat::AMat{T}) where T<:Gray + n, m = size(mat) if is_seriestype_supported(:image) seriestype := :image - n, m = size(mat) SliceIt, 1:m, 1:n, Surface(mat) else seriestype := :heatmap @@ -371,7 +371,7 @@ end end # try some intervals over which the function may be defined -function tryrange(F::AbstractArray, vec) +function tryrange(F::AbstractArray, vec) rets = [tryrange(f, vec) for f in F] # get the preferred for each maxind = maximum(indexin(rets, vec)) # get the last attempt that succeeded (most likely to fit all) rets .= [tryrange(f, vec[maxind:maxind]) for f in F] # ensure that all functions compute there From eb6c15caba4746ef0bef78a458f20dea664e4cc1 Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Tue, 5 Dec 2017 13:12:10 -0500 Subject: [PATCH 506/720] Update iterator properly This seems to fix #1266 --- src/pipeline.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index e8607337..8dc475cb 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -264,7 +264,7 @@ function _subplot_setup(plt::Plot, d::KW, kw_list::Vector{KW}) # extract subplot/axis attributes from kw and add to sp_attr attr = KW() - for (k,v) in kw + for (k,v) in collect(kw) if haskey(_subplot_defaults, k) || haskey(_axis_defaults_byletter, k) attr[k] = pop!(kw, k) end From 70bead1eb1347312f0a929567b5d58ff6d5f823d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 5 Dec 2017 22:09:18 +0100 Subject: [PATCH 507/720] support old PlotTheme type --- src/themes.jl | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 40a9e1f8..5107bcde 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -3,13 +3,35 @@ Specify the colour theme for plots. """ -function theme(s::Symbol; kw...) +function theme(s::Symbol, kw...) + thm = PlotThemes._themes[s] + defaults = if :defaults in fieldnames(thm) + thm.defaults + else # old PlotTheme type + defs = KW( + :bg => thm.bg_secondary, + :bginside => thm.bg_primary, + :fg => thm.lines, + :fgtext => thm.text, + :fgguide => thm.text, + :fglegend => thm.text, + :palette => thm.palette, + ) + if thm.gradient != nothing + push!(defs, :gradient => thm.gradient) + end + defs + end + _theme(s, defaults, kw...) +end + + +function _theme(s::Symbol, defaults::KW; kw...) # Reset to defaults to overwrite active theme reset_defaults() - thm = PlotThemes._themes[s] # Set the theme's gradient as default - if haskey(thm.defaults, :gradient) + if haskey(defaults, :gradient) PlotUtils.clibrary(:misc) PlotUtils.default_cgrad(default = :sequential, sequential = PlotThemes.gradient_name(s)) else @@ -31,7 +53,7 @@ function theme(s::Symbol; kw...) end # Set the theme's defaults - default(; thm.defaults..., kw...) + default(; defaults..., kw...) return end From a8380334df087868989b5dbb8a48fe68c24ecd26 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 5 Dec 2017 22:28:22 +0100 Subject: [PATCH 508/720] fix kw support --- src/themes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes.jl b/src/themes.jl index 5107bcde..52420381 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -3,7 +3,7 @@ Specify the colour theme for plots. """ -function theme(s::Symbol, kw...) +function theme(s::Symbol; kw...) thm = PlotThemes._themes[s] defaults = if :defaults in fieldnames(thm) thm.defaults From 0f3928ec9ac6f9ecf366a112b771e1efd9d221aa Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 5 Dec 2017 22:29:56 +0100 Subject: [PATCH 509/720] fix kw support --- src/themes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/themes.jl b/src/themes.jl index 52420381..8fc47c8f 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -22,7 +22,7 @@ function theme(s::Symbol; kw...) end defs end - _theme(s, defaults, kw...) + _theme(s, defaults; kw...) end From bb687e47cc9aa5d294cf0c44007e69ef5d5f875d Mon Sep 17 00:00:00 2001 From: Tom Breloff Date: Tue, 5 Dec 2017 21:14:08 -0500 Subject: [PATCH 510/720] change author section --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 16f70198..65116717 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ -#### Author: Thomas Breloff (@tbreloff) +#### Created by Tom Breloff (@tbreloff) + +#### Maintained by the [JuliaPlot members](https://github.com/orgs/JuliaPlots/people) Plots is a plotting API and toolset. My goals with the package are: From 0db9710e0f385d2c750809a977ce2ec276013a18 Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Wed, 6 Dec 2017 17:46:35 -0300 Subject: [PATCH 511/720] say how to get the list of attributes in `?plot` --- src/plot.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/plot.jl b/src/plot.jl index 38034bec..25742a6a 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -33,7 +33,7 @@ convertSeriesIndex(plt::Plot, n::Int) = n """ -The main plot command. Use `plot` to create a new plot object, and `plot!` to add to an existing one: +The main plot command. Use `plot` to create a new plot object, and `plot!` to add to an existing one: ``` plot(args...; kw...) # creates a new plot window, and sets it to be the current @@ -42,7 +42,8 @@ The main plot command. Use `plot` to create a new plot object, and `plot!` to a ``` There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected. -When you pass in matrices, it splits by columns. See the documentation for more info. +When you pass in matrices, it splits by columns. To see the list of available attributes, use the `plotattr([attr])` +function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. """ # this creates a new plot with args/kw and sets it to be the current plot From 9b8510ab3e5ad2313a6cf49acf6f77ec603eae32 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 6 Dec 2017 23:19:35 +0100 Subject: [PATCH 512/720] added scatterpath series recipe --- src/recipes.jl | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/recipes.jl b/src/recipes.jl index bae34819..74711add 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -102,6 +102,25 @@ end end @deps vline path +# --------------------------------------------------------------------------- +# path and scatter + +# create a path from steps +@recipe function f(::Type{Val{:scatterpath}}, x, y, z) + x := x + y := y + seriestype := :scatter + @series begin + seriestype := :path + label := "" + primary := false + () + end +() +end +@deps scatterpath path scatter + + # --------------------------------------------------------------------------- # steps From 986bd02e5eca411119a24e33ea3d05e86bccf8d6 Mon Sep 17 00:00:00 2001 From: Marcelo Forets Date: Wed, 6 Dec 2017 22:33:47 -0300 Subject: [PATCH 513/720] Update plot.jl --- src/plot.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plot.jl b/src/plot.jl index 25742a6a..06affdbe 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -43,7 +43,8 @@ The main plot command. Use `plot` to create a new plot object, and `plot!` to ad There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected. When you pass in matrices, it splits by columns. To see the list of available attributes, use the `plotattr([attr])` -function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. +function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. Pass any attribute to `plotattr` +as a String to look up it's docstring; e.g. `plotattr("seriestype")`. """ # this creates a new plot with args/kw and sets it to be the current plot From 66f08cc1a3ecb916f132b513980bee1fc5071513 Mon Sep 17 00:00:00 2001 From: Michael Krabbe Borregaard Date: Thu, 7 Dec 2017 08:52:09 +0100 Subject: [PATCH 514/720] fix typo on docstring --- src/plot.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plot.jl b/src/plot.jl index 06affdbe..5f8f69d9 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -44,7 +44,7 @@ The main plot command. Use `plot` to create a new plot object, and `plot!` to ad There are lots of ways to pass in data, and lots of keyword arguments... just try it and it will likely work as expected. When you pass in matrices, it splits by columns. To see the list of available attributes, use the `plotattr([attr])` function, where `attr` is the symbol `:Series:`, `:Subplot:`, `:Plot` or `:Axis`. Pass any attribute to `plotattr` -as a String to look up it's docstring; e.g. `plotattr("seriestype")`. +as a String to look up its docstring; e.g. `plotattr("seriestype")`. """ # this creates a new plot with args/kw and sets it to be the current plot From 6a3495819abfd606ab04cc1853719f554f6bc572 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 7 Dec 2017 13:10:26 +0100 Subject: [PATCH 515/720] update news --- NEWS.md | 39 ++++++++++++++++++++++++++++++++++++++- src/Plots.jl | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 966c3500..f9470a6d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ #### notes on release changes, ongoing development, and future planned work -- All new development should target 0.13! +- All new development should target 0.14! - Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - `backports` branch is for Julia 0.5 @@ -11,6 +11,43 @@ --- ## (current master) +## 0.14.0 + +- remove use of imagemagick; saving gifs now requires ffmpeg +- improvements to ffmpeg gif quality and speed +- overhaul of fonts, allows setting fonts in recipes and with magic arguments +- added `camera` attribute to control camera position for 3d plots +- added `showaxis` attribute to control which axes to display +- improvements of polar plots axes, and better backend consistency +- changed the 'spy' recipe back to using heatmap +- added `scatterpath` seriestype +- allow plotlyjs to save svg +- add `reset_defaults()` function to reset plot defaults +- update syntax to 0.6 +- make `fill = true` fill to 0 rather than to 1 +- use new `@df` syntax in StatPlots examples +- allow changing the color of legend box +- implement `title_location` for gr +- add `hline` marker to pgfplots - fixes errorbars +- pyplot legends now show marker types +- pyplot colorbars take font style from y axis +- pyplot tickmarks color the same as axis color +- allow setting linewidth for contour in gr +- allow legend to be outside plot area for pgfplots +- expand axis extrema for heatmap +- extendg grid lines to axis limits +- fix `line_z` for pyplot and gr +- fixed colorbar problem for flipped axes with gr +- fix marker_z for 3d plots in gr +- fix `weights` functionality for histograms +- fix gr annotations with colorbar +- fix aspect ratio in gr +- fix "hidden window" problem after savefig in gr +- fix pgfplots logscale ticks error +- fix pgfplots legends symbols +- fix axis linking for plotlyjs +- fix plotting of grayscale images + ## 0.13.1 - fix a bug when passing a vector of functions with no bounds (e.g. `plot([sin, cos])`) diff --git a/src/Plots.jl b/src/Plots.jl index 51d70256..5d66ea2a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 34567e128297889e99a27169a7c01c26857e1ebe Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Thu, 7 Dec 2017 13:12:02 +0100 Subject: [PATCH 516/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 5d66ea2a..51d70256 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From bd42d9e7cc3194fff8b18338af231b5798208b51 Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Thu, 7 Dec 2017 20:56:54 -0500 Subject: [PATCH 517/720] Use the :fontsize labels so the scalefontsizes command works Fixes #1294 --- src/args.jl | 8 ++++---- src/components.jl | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/args.jl b/src/args.jl index 15734286..390ba5f1 100644 --- a/src/args.jl +++ b/src/args.jl @@ -419,10 +419,10 @@ const _all_defaults = KW[ const _initial_defaults = deepcopy(_all_defaults) # to be able to reset font sizes to initial values -const _initial_fontsizes = Dict(:titlefont => _subplot_defaults[:titlefontsize], - :legendfont => _subplot_defaults[:legendfontsize], - :tickfont => _axis_defaults[:tickfontsize], - :guidefont => _axis_defaults[:guidefontsize]) +const _initial_fontsizes = Dict(:titlefontsize => _subplot_defaults[:titlefontsize], + :legendfontsize => _subplot_defaults[:legendfontsize], + :tickfontsize => _axis_defaults[:tickfontsize], + :guidefontsize => _axis_defaults[:guidefontsize]) const _all_args = sort(collect(union(map(keys, _all_defaults)...))) diff --git a/src/components.jl b/src/components.jl index 25784f1e..7f452b97 100644 --- a/src/components.jl +++ b/src/components.jl @@ -305,7 +305,7 @@ end function scalefontsize(k::Symbol, factor::Number) f = default(k) - f.pointsize = round(Int, factor * f.pointsize) + f = round(Int, factor * f) default(k, f) end @@ -315,7 +315,7 @@ end Scales all **current** font sizes by `factor`. For example `scalefontsizes(1.1)` increases all current font sizes by 10%. To reset to initial sizes, use `scalefontsizes()` """ function scalefontsizes(factor::Number) - for k in (:titlefont, :guidefont, :tickfont, :legendfont) + for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize) scalefontsize(k, factor) end end @@ -326,10 +326,10 @@ end Resets font sizes to initial default values. """ function scalefontsizes() - for k in (:titlefont, :guidefont, :tickfont, :legendfont) + for k in (:titlefontsize, :guidefontsize, :tickfontsize, :legendfontsize) f = default(k) if k in keys(_initial_fontsizes) - factor = f.pointsize / _initial_fontsizes[k] + factor = f / _initial_fontsizes[k] scalefontsize(k, 1.0/factor) end end From c76ca2dd6e35e924f33c291dd4755bfcb0facf07 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 11 Dec 2017 09:27:02 +0100 Subject: [PATCH 518/720] add showtheme recipe --- src/themes.jl | 123 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 7 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index 8fc47c8f..adf9df24 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -4,11 +4,16 @@ Specify the colour theme for plots. """ function theme(s::Symbol; kw...) + defaults = _get_defaults(s) + _theme(s, defaults; kw...) +end + +function _get_defaults(s::Symbol) thm = PlotThemes._themes[s] - defaults = if :defaults in fieldnames(thm) - thm.defaults + if :defaults in fieldnames(thm) + return thm.defaults else # old PlotTheme type - defs = KW( + defaults = KW( :bg => thm.bg_secondary, :bginside => thm.bg_primary, :fg => thm.lines, @@ -18,14 +23,12 @@ function theme(s::Symbol; kw...) :palette => thm.palette, ) if thm.gradient != nothing - push!(defs, :gradient => thm.gradient) + push!(defaults, :gradient => thm.gradient) end - defs + return defaults end - _theme(s, defaults; kw...) end - function _theme(s::Symbol, defaults::KW; kw...) # Reset to defaults to overwrite active theme reset_defaults() @@ -58,3 +61,109 @@ function _theme(s::Symbol, defaults::KW; kw...) end @deprecate set_theme(s) theme(s) + +@userplot ShowTheme + +_color_functions = KW( + :protanopic => protanopic, + :deuteranopic => deuteranopic, + :tritanopic => tritanopic, +) +_get_showtheme_args(thm::Symbol) = thm, identity +_get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func, identity) + +@recipe function showtheme(st::ShowTheme) + thm, cfunc = _get_showtheme_args(st.args...) + defaults = _get_defaults(thm) + + # get the gradient + gradient_colors = pop!(defaults, :gradient, cgrad(:inferno).colors) + gradient = cgrad(cfunc.(RGB.(gradient_colors))) + + # get the palette + palette = pop!(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17)) + palette = cfunc.(RGB.(palette)) + + # apply the theme + for k in keys(defaults) + def = defaults[k] + arg = get(_keyAliases, k, k) + plotattributes[arg] = if typeof(def) <: Colorant + cfunc(RGB(def)) + elseif eltype(def) <: Colorant + cfunc.(RGB.(def)) + elseif contains(string(arg), "color") + cfunc.(RGB.(plot_color.(def))) + else + def + end + end + + srand(1) + + label := "" + colorbar := false + layout := (2, 3) + + for j in 1:4 + @series begin + subplot := 1 + palette := palette + seriestype := :path + linewidth := 2 + cumsum(randn(50)) + end + + @series begin + subplot := 2 + seriestype := :scatter + palette := palette + markersize := 5 + markerstrokewidth := 0 + marker := (:circle, :diamond, :star5, :square)[j] + randn(10), randn(10) + end + end + + @series begin + subplot := 3 + seriestype := :histogram + palette := palette + randn(1000) .+ (0:2:4)' + end + + f(r) = sin(r) / r + _norm(x, y) = norm([x, y]) + x = y = linspace(-3π, 3π, 30) + z = f.(_norm.(x, y')) + wi = 2:3:30 + + @series begin + subplot := 4 + seriestype := :heatmap + seriescolor := gradient + x, y, z + end + + @series begin + subplot := 5 + seriestype := :surface + seriescolor := gradient + x, y, z + end + + n = 100 + ts = linspace(0, 10π, n) + x = ts .* cos.(ts) + y = (0.1ts) .* sin.(ts) + z = 1:n + + @series begin + subplot := 6 + seriescolor := gradient + linewidth := 3 + line_z := z + x, y, z + end + +end From 5e5f3c1e957b295525e67bea1a87891b57b4273d Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 11 Dec 2017 10:26:19 +0100 Subject: [PATCH 519/720] abline! does not change axis limits --- src/recipes.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 74711add..5eab486f 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -985,9 +985,11 @@ end # ------------------------------------------------- -"Adds a+bx... straight line over the current plot" +"Adds a+bx... straight line over the current plot, without changing the axis limits" function abline!(plt::Plot, a, b; kw...) - plot!(plt, [ignorenan_extrema(plt)...], x -> b + a*x; kw...) + xl, yl = xlims(plt), ylims(plt) + x1, x2 = max(xl[1], (yl[1] - b)/a), min(xl[2], (yl[2] - b)/a) + plot!(plt, x -> b + a*x, x1, x2; kw...) end abline!(args...; kw...) = abline!(current(), args...; kw...) From 2a819c2849fce014fe3f93053a10d0b92d46e9c0 Mon Sep 17 00:00:00 2001 From: SimonDanisch Date: Mon, 11 Dec 2017 12:34:21 +0100 Subject: [PATCH 520/720] fix JuliaGL/GLVisualize.jl#238 --- src/backends/glvisualize.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f89b8afc..8861fa46 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -336,7 +336,7 @@ end function extract_stroke(d, kw_args) extract_c(d, kw_args, :line) if haskey(d, :linewidth) - kw_args[:thickness] = d[:linewidth] * 3 + kw_args[:thickness] = Float32(d[:linewidth] * 3) end end @@ -404,7 +404,7 @@ function extract_linestyle(d, kw_args) haskey(d, :linestyle) || return ls = d[:linestyle] lw = d[:linewidth] - kw_args[:thickness] = lw + kw_args[:thickness] = Float32(lw) if ls == :dash points = [0.0, lw, 2lw, 3lw, 4lw] insert_pattern!(points, kw_args) @@ -576,7 +576,7 @@ function draw_grid_lines(sp, grid_segs, thickness, style, model, color) ) d = Dict( :linestyle => style, - :linewidth => thickness, + :linewidth => Float32(thickness), :linecolor => color ) Plots.extract_linestyle(d, kw_args) @@ -1350,7 +1350,7 @@ function gl_surface(x,y,z, kw_args) end color = get(kw_args, :stroke_color, RGBA{Float32}(0,0,0,1)) kw_args[:color] = color - kw_args[:thickness] = get(kw_args, :stroke_width, 1f0) + kw_args[:thickness] = Float32(get(kw_args, :stroke_width, 1f0)) kw_args[:indices] = faces delete!(kw_args, :stroke_color) delete!(kw_args, :stroke_width) From f655b2313c5d15d8d31c690ae61ccdd58d24b397 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 8 Dec 2017 21:30:57 +0000 Subject: [PATCH 521/720] Fix default log scale ticks in GR backend. --- src/backends/gr.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 1530d19e..ed66c185 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -860,7 +860,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv)) + # ensure correct dispatch in gr_text for automatic log ticks + dv = xaxis[:scale] in (:ln, :log10, :log2) && xaxis[:ticks] == :auto ? string(dv, "\\ ") : string(dv) + gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), dv) end end @@ -871,7 +873,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi - gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv)) + # ensure correct dispatch in gr_text for automatic log ticks + dv = yaxis[:scale] in (:ln, :log10, :log2) && yaxis[:ticks] == :auto ? string(dv, "\\ ") : string(dv) + gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, dv) end end From f80afddd8f393aa8e4338634a1d0f9aba0f4a0ad Mon Sep 17 00:00:00 2001 From: Josh Day Date: Tue, 12 Dec 2017 15:15:12 -0500 Subject: [PATCH 522/720] add strokewidth and bar_width for plotly's bar --- src/backends/plotly.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 20edb066..4dc7a675 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -541,7 +541,10 @@ function plotly_series(plt::Plot, series::Series) else y, x, "h" end - d_out[:marker] = KW(:color => rgba_string(series[:fillcolor])) + d_out[:width] = series[:bar_width] + info(series[:strokewidth]) + d_out[:marker] = KW(:color => rgba_string(series[:fillcolor]), + :width => series[:strokewidth]) elseif st == :heatmap d_out[:type] = "heatmap" From 50bec7a461920d08f3359aa6f147a3dad012f280 Mon Sep 17 00:00:00 2001 From: Josh Day Date: Tue, 12 Dec 2017 15:18:17 -0500 Subject: [PATCH 523/720] cleanup --- src/backends/plotly.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 4dc7a675..85ae90bf 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -542,7 +542,6 @@ function plotly_series(plt::Plot, series::Series) y, x, "h" end d_out[:width] = series[:bar_width] - info(series[:strokewidth]) d_out[:marker] = KW(:color => rgba_string(series[:fillcolor]), :width => series[:strokewidth]) From 1645c3f66b19c229b188dc650dd9f67970008a18 Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Wed, 13 Dec 2017 15:07:54 -0500 Subject: [PATCH 524/720] Add linestyle argument to the legend This fixes #1305 --- src/backends/pyplot.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 8a9c7680..fb97190d 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1236,6 +1236,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), + linestyle = py_linestyle(:path,series[:linestyle]), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), markerfacecolor = py_markercolor(series) From ee6dbb9ac782191f9f1449203219bc4fd9a3f39b Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Wed, 13 Dec 2017 18:55:48 -0500 Subject: [PATCH 525/720] add line_z and marker_z example --- src/examples.jl | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/examples.jl b/src/examples.jl index e43fa6fe..ce527014 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -416,6 +416,22 @@ attribute. The default framestyle is `:axes`. end)] ), +PlotExample("Lines and markers with varying colors", +""" +You can use the `line_z` and `marker_z` properties to associate a color with +each line segment or marker in the plot. +""" + [:(begin + t = linspace(0, 1, 100) + θ = 6π .* t + x = t .* cos.(θ) + y = t .* sin.(θ) + p1 = plot(x, y, line_z=t, linewidth=3, legend=false) + p2 = scatter(x, y, marker_z=t, color=:bluesreds, legend=false) + plot(p1, p2) + end)] +), + ] # --------------------------------------------------------------------------------- From 349b6e8254938ec49468830ed27c36f053aeed0e Mon Sep 17 00:00:00 2001 From: Robin Deits Date: Wed, 13 Dec 2017 18:59:15 -0500 Subject: [PATCH 526/720] fix typo --- src/examples.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/examples.jl b/src/examples.jl index ce527014..57ed7b3e 100644 --- a/src/examples.jl +++ b/src/examples.jl @@ -420,7 +420,7 @@ PlotExample("Lines and markers with varying colors", """ You can use the `line_z` and `marker_z` properties to associate a color with each line segment or marker in the plot. -""" +""", [:(begin t = linspace(0, 1, 100) θ = 6π .* t From 1aa4e7eee631bd32a498f7202d6bce5cc6d06ebc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 14 Dec 2017 11:02:59 +0100 Subject: [PATCH 527/720] update news.md --- NEWS.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index f9470a6d..fa8187af 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,15 @@ --- ## (current master) +## 0.14.1 + +- Add linestyle argument to the legend +- Plotly: bar_width and stroke_width support for bar plots +- abline! does not change axis limits +- Fix default log scale ticks in GR backend +- Use the :fontsize keys so the scalefontsizes command works +- Prepare support for new PlotTheme type in PlotThemes + ## 0.14.0 - remove use of imagemagick; saving gifs now requires ffmpeg From 5d1876ab6d5b277dd0b43b2ea1cf03c6feb0d042 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 14 Dec 2017 11:03:52 +0100 Subject: [PATCH 528/720] precompile off --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 51d70256..5d66ea2a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From 8fe902e96c6c839fc8ac04673007ccccc51fcb1b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 14 Dec 2017 11:29:55 +0100 Subject: [PATCH 529/720] precompile on --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 5d66ea2a..51d70256 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 938c83533b165541ea0a0f744a918eebd70dfa21 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 14 Dec 2017 19:25:59 +0000 Subject: [PATCH 530/720] Fix slicing of ribbons. --- src/series.jl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/series.jl b/src/series.jl index a5425e94..ff8b5d95 100644 --- a/src/series.jl +++ b/src/series.jl @@ -140,6 +140,14 @@ struct SliceIt end end mf = length(fillranges) + rib = pop!(plotattributes, :ribbon, nothing) + ribbons, _ = if typeof(rib) <: Number + ([fr],nothing) + else + convertToAnyVector(rib, plotattributes) + end + mr = length(ribbons) + # @show zs mx = length(xs) @@ -156,6 +164,10 @@ struct SliceIt end fr = fillranges[mod1(i,mf)] di[:fillrange] = isa(fr, Function) ? map(fr, di[:x]) : fr + # handle ribbons + rib = ribbons[mod1(i,mr)] + di[:ribbon] = isa(rib, Function) ? map(rib, di[:x]) : rib + push!(series_list, RecipeData(di, ())) end end From 3d323a734dffa5fa3fd4fdf8db955d14057613b8 Mon Sep 17 00:00:00 2001 From: Josh Day Date: Fri, 15 Dec 2017 00:21:44 -0500 Subject: [PATCH 531/720] fix plotly histogram --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 85ae90bf..70bb7ea9 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -543,7 +543,7 @@ function plotly_series(plt::Plot, series::Series) end d_out[:width] = series[:bar_width] d_out[:marker] = KW(:color => rgba_string(series[:fillcolor]), - :width => series[:strokewidth]) + :line => KW(:width => series[:linewidth])) elseif st == :heatmap d_out[:type] = "heatmap" From 81782c3927d17e63659cfe1b80fe5a92c2838419 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 15 Dec 2017 09:18:37 +0100 Subject: [PATCH 532/720] turn off precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 51d70256..5d66ea2a 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(true) +__precompile__(false) module Plots From d52b2a9adc465ccaae45702c795fcaee0a42f43a Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 15 Dec 2017 09:22:20 +0100 Subject: [PATCH 533/720] update news --- NEWS.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/NEWS.md b/NEWS.md index fa8187af..e96da86f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,12 @@ --- ## (current master) +## 0.14.2 + +- fix plotly bar lines bug +- allow passing multiple series to `ribbon` +- add a new example for `line_z` + ## 0.14.1 - Add linestyle argument to the legend From 216a9c3666516243f468b9c5c5c28da11ba50e93 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 15 Dec 2017 09:24:00 +0100 Subject: [PATCH 534/720] reactivate precompilation --- src/Plots.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index 5d66ea2a..51d70256 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -1,4 +1,4 @@ -__precompile__(false) +__precompile__(true) module Plots From 802b20be6f4d81b664d9d7c1ae931312db326de5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 15 Dec 2017 10:30:56 +0100 Subject: [PATCH 535/720] update showtheme recipe --- src/themes.jl | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/themes.jl b/src/themes.jl index adf9df24..64f15102 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -77,15 +77,16 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func defaults = _get_defaults(thm) # get the gradient - gradient_colors = pop!(defaults, :gradient, cgrad(:inferno).colors) + gradient_colors = get(defaults, :gradient, cgrad(:inferno).colors) gradient = cgrad(cfunc.(RGB.(gradient_colors))) # get the palette - palette = pop!(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17)) + palette = get(defaults, :palette, get_color_palette(:auto, plot_color(:white), 17)) palette = cfunc.(RGB.(palette)) # apply the theme for k in keys(defaults) + k in (:gradient, :palette) && continue def = defaults[k] arg = get(_keyAliases, k, k) plotattributes[arg] = if typeof(def) <: Colorant @@ -110,7 +111,6 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func subplot := 1 palette := palette seriestype := :path - linewidth := 2 cumsum(randn(50)) end @@ -118,8 +118,6 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func subplot := 2 seriestype := :scatter palette := palette - markersize := 5 - markerstrokewidth := 0 marker := (:circle, :diamond, :star5, :square)[j] randn(10), randn(10) end From a637f43edd42479e83e5182a9458cc2bb6d35689 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 15 Dec 2017 22:38:53 +0000 Subject: [PATCH 536/720] Only base clims on z values when series is colored by z. --- src/utils.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index c5a4baa0..081cc7d3 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -553,8 +553,9 @@ zlims(sp_idx::Int = 1) = zlims(current(), sp_idx) function get_clims(sp::Subplot) zmin, zmax = Inf, -Inf + z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface) for series in series_list(sp) - for vals in (series[:z], series[:line_z], series[:marker_z], series[:fill_z]) + for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, [:line_z], series[:marker_z], series[:fill_z]) if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real) zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...) elseif (vals != nothing) && (eltype(vals) <: Real) From e402f5dfce2be0c9e127171debb804f96dcab194 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 16 Dec 2017 20:10:55 +0000 Subject: [PATCH 537/720] Fix mismatched legend color when linecolor is given. --- 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 fb97190d..2cfe730d 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1234,7 +1234,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) ) elseif series[:seriestype] == :path PyPlot.plt[:Line2D]((0,1),(0,0), - color = py_color(_cycle(series[:fillcolor],1)), + color = py_color(_cycle(series[:linecolor],1)), linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), linestyle = py_linestyle(:path,series[:linestyle]), marker = py_marker(series[:markershape]), From 5be95be9aeffbe413cf7beb635dd69be25a76a0d Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Sat, 16 Dec 2017 15:07:22 +0100 Subject: [PATCH 538/720] gr: improve PNG output (resolution) --- src/backends/gr.jl | 16 ++++++++++++---- test/runtests.jl | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ed66c185..bdafb772 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -543,7 +543,7 @@ function gr_set_gradient(c) end # this is our new display func... set up the viewport_canvas, compute bounding boxes, and display each subplot -function gr_display(plt::Plot) +function gr_display(plt::Plot, fmt="") GR.clearws() # collect some monitor/display sizes in meters and pixels @@ -554,17 +554,25 @@ function gr_display(plt::Plot) # compute the viewport_canvas, normalized to the larger dimension viewport_canvas = Float64[0,1,0,1] w, h = plt[:size] + if !haskey(ENV, "PLOTS_TEST") + dpi_factor = plt[:dpi] / DPI + if fmt == "png" + dpi_factor *= 6 + end + else + dpi_factor = 1 + end gr_plot_size[:] = [w, h] if w > h ratio = float(h) / w - msize = display_width_ratio * w + msize = display_width_ratio * w * dpi_factor GR.setwsviewport(0, msize, 0, msize * ratio) GR.setwswindow(0, 1, 0, ratio) viewport_canvas[3] *= ratio viewport_canvas[4] *= ratio else ratio = float(w) / h - msize = display_height_ratio * h + msize = display_height_ratio * h * dpi_factor GR.setwsviewport(0, msize * ratio, 0, msize) GR.setwswindow(0, ratio, 0, 1) viewport_canvas[1] *= ratio @@ -1335,7 +1343,7 @@ for (mime, fmt) in _gr_mimeformats env = get(ENV, "GKSwstype", "0") ENV["GKSwstype"] = $fmt ENV["GKS_FILEPATH"] = filepath - gr_display(plt) + gr_display(plt, $fmt) GR.emergencyclosegks() write(io, readstring(filepath)) rm(filepath) diff --git a/test/runtests.jl b/test/runtests.jl index 4f0b2ad0..62653f4e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,6 +8,7 @@ default(show=false, reuse=true) img_eps = isinteractive() ? 1e-2 : 10e-2 @testset "GR" begin + ENV["PLOTS_TEST"] = "true" ENV["GKSwstype"] = "100" @test gr() == Plots.GRBackend() @test backend() == Plots.GRBackend() From 6cdccf4353c262bb489b2d398ecb3317c88148a3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 17 Dec 2017 16:44:20 +0100 Subject: [PATCH 539/720] add missing 'series' --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 081cc7d3..5d1222bd 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -555,7 +555,7 @@ function get_clims(sp::Subplot) zmin, zmax = Inf, -Inf z_colored_series = (:contour, :contour3d, :heatmap, :histogram2d, :surface) for series in series_list(sp) - for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, [:line_z], series[:marker_z], series[:fill_z]) + for vals in (series[:seriestype] in z_colored_series ? series[:z] : nothing, series[:line_z], series[:marker_z], series[:fill_z]) if (typeof(vals) <: AbstractSurface) && (eltype(vals.surf) <: Real) zmin, zmax = _update_clims(zmin, zmax, ignorenan_extrema(vals.surf)...) elseif (vals != nothing) && (eltype(vals) <: Real) From a1a7dcd6b82b01a74aa633763d3a29932388fdaf Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 17 Dec 2017 17:04:05 +0100 Subject: [PATCH 540/720] reduce tick number in heatmap plot --- src/themes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/themes.jl b/src/themes.jl index 64f15102..c2b2aee1 100644 --- a/src/themes.jl +++ b/src/themes.jl @@ -140,6 +140,7 @@ _get_showtheme_args(thm::Symbol, func::Symbol) = thm, get(_color_functions, func subplot := 4 seriestype := :heatmap seriescolor := gradient + ticks := -5:5:5 x, y, z end From 89b5582d0de6756daaafd42859d9dad11265a051 Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Sun, 17 Dec 2017 16:13:35 -0500 Subject: [PATCH 541/720] Map rgba_string over :color vector and cycle through result --- src/backends/plotly.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 70bb7ea9..f7d24acd 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -542,7 +542,7 @@ function plotly_series(plt::Plot, series::Series) y, x, "h" end d_out[:width] = series[:bar_width] - d_out[:marker] = KW(:color => rgba_string(series[:fillcolor]), + d_out[:marker] = KW(:color => _cycle(rgba_string.(series[:fillcolor]),eachindex(series[:x])), :line => KW(:width => series[:linewidth])) elseif st == :heatmap @@ -610,14 +610,14 @@ function plotly_series(plt::Plot, series::Series) :size => 2 * series[:markersize], # :color => rgba_string(series[:markercolor]), :line => KW( - :color => rgba_string(series[:markerstrokecolor]), + :color => _cycle(rgba_string.(series[:markerstrokecolor]),eachindex(series[:x])), :width => series[:markerstrokewidth], ), ) # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient if series[:marker_z] == nothing - d_out[:marker][:color] = rgba_string(series[:markercolor]) + d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]),eachindex(series[:x])) else # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) # grad = as_gradient(series[:markercolor], series[:markeralpha]) From 6ff4dce62a3a272ec2c0ac997b1bd279f8fd0905 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 18 Dec 2017 08:47:15 +0100 Subject: [PATCH 542/720] Don't add `abline!` if outside plot window --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 5eab486f..07ac0c1b 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -989,7 +989,7 @@ end function abline!(plt::Plot, a, b; kw...) xl, yl = xlims(plt), ylims(plt) x1, x2 = max(xl[1], (yl[1] - b)/a), min(xl[2], (yl[2] - b)/a) - plot!(plt, x -> b + a*x, x1, x2; kw...) + x2 > x1 && plot!(plt, x -> b + a*x, x1, x2; kw...) end abline!(args...; kw...) = abline!(current(), args...; kw...) From b1817e513be1eaa64a9a17f524c9f678d5d92f70 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Mon, 18 Dec 2017 09:19:31 +0100 Subject: [PATCH 543/720] Don't return false --- src/recipes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 07ac0c1b..8c669a78 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -989,7 +989,11 @@ end function abline!(plt::Plot, a, b; kw...) xl, yl = xlims(plt), ylims(plt) x1, x2 = max(xl[1], (yl[1] - b)/a), min(xl[2], (yl[2] - b)/a) - x2 > x1 && plot!(plt, x -> b + a*x, x1, x2; kw...) + if x2 > x1 + plot!(plt, x -> b + a*x, x1, x2; kw...) + else + nothing + end end abline!(args...; kw...) = abline!(current(), args...; kw...) From 50df9a70c9fb9c207368358b451543afdfbfc1bc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 18 Dec 2017 22:15:57 +0100 Subject: [PATCH 544/720] fix gr 3d grid appearance --- src/backends/gr.jl | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index bdafb772..881c5e8d 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -788,10 +788,23 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) ztick = GR.tick(zmin, zmax) / 2 ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1]) - # GR.setlinetype(GR.LINETYPE_DOTTED) - xaxis[:grid] && GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) - yaxis[:grid] && GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) - zaxis[:grid] && GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) + if xaxis[:grid] + gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) + GR.settransparency(xaxis[:gridalpha]) + GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) + end + if yaxis[:grid] + gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) + GR.settransparency(yaxis[:gridalpha]) + GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) + end + if zaxis[:grid] + gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid]) + GR.settransparency(zaxis[:gridalpha]) + GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) + end + gr_set_line(1, :solid, xaxis[:foreground_color_axis]) + GR.settransparency(1) GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) From 95a5b5025a7e0b57e1af20abf5c3bd1c86cd9cc4 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Tue, 19 Dec 2017 12:05:11 +0000 Subject: [PATCH 545/720] Fix PyPlot ignoring alpha values of images --- 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 2cfe730d..461c8e6f 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -736,7 +736,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) z = if eltype(img) <: Colors.AbstractGray float(img) elseif eltype(img) <: Colorant - map(c -> Float64[red(c),green(c),blue(c)], img) + map(c -> Float64[red(c),green(c),blue(c),alpha(c)], img) else z # hopefully it's in a data format that will "just work" with imshow end From 32d59fff615df6fd098ca434c9faf1e2fb16f444 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 16 Nov 2017 22:27:13 +0000 Subject: [PATCH 546/720] Turn off scaled ticks for PGFPlots. --- src/backends/pgfplots.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index d83917d0..13f9daad 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -272,6 +272,9 @@ function pgf_axis(sp::Subplot, letter) style = [] kw = KW() + # turn off scaled ticks + push!(style, "scaled $(letter) ticks = false") + # set to supported framestyle framestyle = pgf_framestyle(sp[:framestyle]) From 62ca787e6e3d9076b062064a534095706b875889 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 23 Dec 2017 00:35:44 +0000 Subject: [PATCH 547/720] Fix scientific formatter for GR and PGFPlots. --- src/backends/gr.jl | 25 +++++++++++++++++++++++-- src/backends/pgfplots.jl | 2 ++ src/utils.jl | 25 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 881c5e8d..5e2d6ed6 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -222,6 +222,13 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) + rtick_labels = if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto + rtick_labels = string.(convert_sci_unicode.(rtick_labels),"\\ ") + # unicode × messes up superscript alignment so add space to superscript + replace.(rtick_labels, "{", "{ ") + else + rtick_labels + end #draw angular grid if xaxis[:grid] @@ -882,7 +889,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) # ensure correct dispatch in gr_text for automatic log ticks - dv = xaxis[:scale] in (:ln, :log10, :log2) && xaxis[:ticks] == :auto ? string(dv, "\\ ") : string(dv) + dv = if xaxis[:scale] in (:ln, :log10, :log2) && xaxis[:ticks] == :auto + string(dv, "\\ ") + elseif xaxis[:formatter] == :scientific && xaxis[:ticks] == :auto + # unicode × messes up superscript alignment so add space to superscript + string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ") + else + string(dv) + end gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), dv) end end @@ -895,7 +909,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi # ensure correct dispatch in gr_text for automatic log ticks - dv = yaxis[:scale] in (:ln, :log10, :log2) && yaxis[:ticks] == :auto ? string(dv, "\\ ") : string(dv) + dv = if yaxis[:scale] in (:ln, :log10, :log2) && yaxis[:ticks] == :auto + string(dv, "\\ ") + elseif yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto + # unicode × messes up superscript alignment so add space to superscript + string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ") + else + string(dv) + end gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, dv) end end diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 13f9daad..db4e8b26 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -329,6 +329,7 @@ function pgf_axis(sp::Subplot, letter) push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}")) elseif axis[:showaxis] tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2] + tick_labels = axis[:formatter] == :scientific ? string.("\$", convert_sci_unicode.(tick_labels), "\$") : tick_labels push!(style, string(letter, "ticklabels = {", join(tick_labels,","), "}")) else push!(style, string(letter, "ticklabels = {}")) @@ -500,6 +501,7 @@ end function _display(plt::Plot{PGFPlotsBackend}) # prepare the object + PGFPlots.pushPGFPlotsPreamble("\\usepackage{fontspec}") pgfplt = PGFPlots.plot(plt.o) # save an svg diff --git a/src/utils.jl b/src/utils.jl index 5d1222bd..3fc55a88 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1048,3 +1048,28 @@ guidefont(ax::Axis) = font( ax[:guidefontrotation], ax[:guidefontcolor], ) + +# --------------------------------------------------------------- +# converts unicode scientific notation unsupported by pgfplots and gr +# into a format that works + +function convert_sci_unicode(label::AbstractString) + unicode_dict = Dict( + '⁰' => "0", + '¹' => "1", + '²' => "2", + '³' => "3", + '⁴' => "4", + '⁵' => "5", + '⁶' => "6", + '⁷' => "7", + '⁸' => "8", + '⁹' => "9", + '⁻' => "-", + "×10" => "×10^{", + ) + for key in keys(unicode_dict) + label = replace(label, key, unicode_dict[key]) + end + string(label, "}") +end From e6df4d977d5b656c6685e334c99c4a80f6af618e Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Sat, 6 Jan 2018 14:54:57 -0500 Subject: [PATCH 548/720] Add a check for ticks==nothing or false Fixes #1336 --- src/axes.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index c1dcff2c..d62667fb 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -552,7 +552,7 @@ function axis_drawing_info(sp::Subplot) end push!(xaxis_segs, (xmin, y1), (xmax, y1)) # don't show the 0 tick label for the origin framestyle - if sp[:framestyle] == :origin && length(xticks) > 1 + if sp[:framestyle] == :origin && !(xticks in (nothing,false)) && length(xticks) > 1 showticks = xticks[1] .!= 0 xticks = (xticks[1][showticks], xticks[2][showticks]) end @@ -591,7 +591,7 @@ function axis_drawing_info(sp::Subplot) end push!(yaxis_segs, (x1, ymin), (x1, ymax)) # don't show the 0 tick label for the origin framestyle - if sp[:framestyle] == :origin && length(yticks) > 1 + if sp[:framestyle] == :origin && !(yticks in (nothing,false)) && length(yticks) > 1 showticks = yticks[1] .!= 0 yticks = (yticks[1][showticks], yticks[2][showticks]) end From f6ed3fbb767d0b1c4ccf70ca7e70fbee6d3fa00f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 8 Jan 2018 12:50:46 +0100 Subject: [PATCH 549/720] allow transparency in heatmaps --- src/backends/gr.jl | 4 ++-- src/backends/plotly.jl | 6 +++--- src/backends/pyplot.jl | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 881c5e8d..c6dcb692 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1082,7 +1082,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) zmin, zmax = clims GR.setspace(zmin, zmax, 0, 90) grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad() - colors = [grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)] for zi=z] + colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z] rgba = map(c -> UInt32( round(Int, alpha(c) * 255) << 24 + round(Int, blue(c) * 255) << 16 + round(Int, green(c) * 255) << 8 + @@ -1207,7 +1207,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if cmap && st != :contour # special colorbar with steps is drawn for contours gr_set_line(1, :solid, yaxis[:foreground_color_axis]) GR.settransparency(1) - gr_colorbar(sp, clims) + gr_colorbar(sp, clims, series[:fillalpha]) end GR.restorestate() diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 70bb7ea9..7a5ad17c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -259,7 +259,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:tickangle] = -axis[:rotation] lims = axis_limits(axis) ax[:range] = map(scalefunc(axis[:scale]), lims) - + if !(axis[:ticks] in (nothing, :none)) ax[:titlefont] = plotly_font(guidefont(axis)) ax[:type] = plotly_scale(axis[:scale]) @@ -289,7 +289,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:showgrid] = false end - + ax end @@ -430,7 +430,7 @@ end function plotly_colorscale(grad::ColorGradient, α) - [[grad.values[i], rgb_string(grad.colors[i])] for i in 1:length(grad.colors)] + [[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in 1:length(grad.colors)] end plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α) # plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 461c8e6f..d2566d44 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -768,6 +768,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex], cmap = py_fillcolormap(series), + alpha = series[:fillalpha], # edgecolors = (series[:linewidth] > 0 ? py_linecolor(series) : "face"), extrakw... ) From 04888646e7f51f40fb0b57c4ad3b7423fe4c5070 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 8 Jan 2018 13:50:16 +0100 Subject: [PATCH 550/720] fix gr --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c6dcb692..e20f96af 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1207,7 +1207,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if cmap && st != :contour # special colorbar with steps is drawn for contours gr_set_line(1, :solid, yaxis[:foreground_color_axis]) GR.settransparency(1) - gr_colorbar(sp, clims, series[:fillalpha]) + gr_colorbar(sp, clims) end GR.restorestate() From dbd5ae46dd66ebc21285700091f0c230f8b795c2 Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Wed, 10 Jan 2018 11:38:11 +0100 Subject: [PATCH 551/720] update news --- NEWS.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NEWS.md b/NEWS.md index e96da86f..d717268c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,17 @@ --- ## (current master) +## 0.14.3 + +- improve resolution of png output of GR with savefig() +- add check for ticks=nothing +- allow transparency in heatmaps +- fix line_z for GR +- fix legendcolor for pyplot +- fix pyplot ignoring alpha values of images +- don't let `abline!` change subplot limits +- update showtheme recipe + ## 0.14.2 - fix plotly bar lines bug From c2b56878fc15881614fa3f1e615ad9adafbda263 Mon Sep 17 00:00:00 2001 From: Josef Heinen Date: Wed, 10 Jan 2018 20:30:10 +0100 Subject: [PATCH 552/720] fixed problems with labels in scientific notation --- src/backends/gr.jl | 34 ++++++++++------------------------ src/utils.jl | 5 ++++- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9869fec6..0be3fd06 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -193,7 +193,7 @@ gr_inqtext(x, y, s::Symbol) = gr_inqtext(x, y, string(s)) function gr_inqtext(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.inqtextext(x, y, s[2:end-1]) - elseif search(s, '\\') != 0 + elseif search(s, '\\') != 0 || contains(s, "10^{") GR.inqtextext(x, y, s) else GR.inqtext(x, y, s) @@ -205,7 +205,7 @@ gr_text(x, y, s::Symbol) = gr_text(x, y, string(s)) function gr_text(x, y, s) if length(s) >= 2 && s[1] == '$' && s[end] == '$' GR.mathtex(x, y, s[2:end-1]) - elseif search(s, '\\') != 0 + elseif search(s, '\\') != 0 || contains(s, "10^{") GR.textext(x, y, s) else GR.text(x, y, s) @@ -222,12 +222,8 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) - rtick_labels = if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto - rtick_labels = string.(convert_sci_unicode.(rtick_labels),"\\ ") - # unicode × messes up superscript alignment so add space to superscript - replace.(rtick_labels, "{", "{ ") - else - rtick_labels + if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto + rtick_labels = convert_sci_unicode(rtick_labels) end #draw angular grid @@ -889,15 +885,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) # ensure correct dispatch in gr_text for automatic log ticks - dv = if xaxis[:scale] in (:ln, :log10, :log2) && xaxis[:ticks] == :auto - string(dv, "\\ ") - elseif xaxis[:formatter] == :scientific && xaxis[:ticks] == :auto - # unicode × messes up superscript alignment so add space to superscript - string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ") - else - string(dv) + if xaxis[:formatter] == :scientific && xaxis[:ticks] == :auto + dv = convert_sci_unicode(dv) end - gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), dv) + gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv)) end end @@ -909,15 +900,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi # ensure correct dispatch in gr_text for automatic log ticks - dv = if yaxis[:scale] in (:ln, :log10, :log2) && yaxis[:ticks] == :auto - string(dv, "\\ ") - elseif yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto - # unicode × messes up superscript alignment so add space to superscript - string(replace(convert_sci_unicode(dv), "{", "{ "), "\\ ") - else - string(dv) + if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto + dv = convert_sci_unicode(dv) end - gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, dv) + gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv)) end end diff --git a/src/utils.jl b/src/utils.jl index 3fc55a88..6b2fb689 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1071,5 +1071,8 @@ function convert_sci_unicode(label::AbstractString) for key in keys(unicode_dict) label = replace(label, key, unicode_dict[key]) end - string(label, "}") + if contains(label, "10^{") + label = string(label, "}") + end + label end From 9b5295ff00a552ac79cbff0934ebf0e4097766b0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 11 Jan 2018 20:11:59 +0100 Subject: [PATCH 553/720] update version for tests --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index b9038d3d..748ef4a8 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.13.1" +const _current_plots_version = v"0.15.0" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From af859b4c139694b643a6d1d97dd897f868eeb8c6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 11 Jan 2018 20:30:47 +0100 Subject: [PATCH 554/720] update version in NEWS.md --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d717268c..b4b51cdd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,7 +11,7 @@ --- ## (current master) -## 0.14.3 +## 0.15.0 - improve resolution of png output of GR with savefig() - add check for ticks=nothing From 8b6dba8301281c92053f77c57940cc11c334be90 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 11 Jan 2018 21:26:33 +0100 Subject: [PATCH 555/720] fix labels with logscales --- src/backends/gr.jl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 0be3fd06..c499a8ad 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -884,9 +884,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - # ensure correct dispatch in gr_text for automatic log ticks - if xaxis[:formatter] == :scientific && xaxis[:ticks] == :auto - dv = convert_sci_unicode(dv) + if xaxis[:ticks] == :auto + # ensure correct dispatch in gr_text for automatic log ticks + if xaxis[:scale] in _logScales + dv = string(dv, "\\ ") + elseif xaxis[:formatter] == :scientific + dv = convert_sci_unicode(dv) + end end gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv)) end @@ -899,9 +903,13 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi - # ensure correct dispatch in gr_text for automatic log ticks - if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto - dv = convert_sci_unicode(dv) + if yaxis[:ticks] == :auto + # ensure correct dispatch in gr_text for automatic log ticks + if yaxis[:scale] in _logScales + dv = string(dv, "\\ ") + elseif yaxis[:formatter] == :scientific + dv = convert_sci_unicode(dv) + end end gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv)) end From 877e7ab940f6e55b47213d7a227cc12f779ab02b Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Sat, 13 Jan 2018 10:07:27 -0500 Subject: [PATCH 556/720] Uncomment convertToAnyVector for Date/DateTime Fixes #1283 --- src/series.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/series.jl b/src/series.jl index ff8b5d95..10cc99bb 100644 --- a/src/series.jl +++ b/src/series.jl @@ -46,7 +46,7 @@ convertToAnyVector(v::Volume, d::KW) = Any[v], nothing # convertToAnyVector(v::AVec{OHLC}, d::KW) = Any[v], nothing # # dates -# convertToAnyVector{D<:Union{Date,DateTime}}(dts::AVec{D}, d::KW) = Any[dts], nothing +convertToAnyVector{D<:Union{Date,DateTime}}(dts::AVec{D}, d::KW) = Any[dts], nothing # list of things (maybe other vectors, functions, or something else) function convertToAnyVector(v::AVec, d::KW) From c21f3810b9c0603b2c984565e75cee0b68ff28c6 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 5 Jan 2018 10:51:41 +0000 Subject: [PATCH 557/720] Fix axis limits not cropping image. --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c499a8ad..ff9cf354 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1208,7 +1208,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, green(c) * 255) << 8 + round(Int, red(c) * 255) ), z) end - GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) + GR.drawimage(0, w, h, 0, w, h, rgba) end # this is all we need to add the series_annotations text From 27e2795576671a18be7110df49d2d248c052b37c Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 13 Jan 2018 16:18:08 +0000 Subject: [PATCH 558/720] Fix deprecation. --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ff9cf354..d10420eb 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1200,7 +1200,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) z = transpose_z(series, series[:z].surf, true)' w, h = size(z) if eltype(z) <: Colors.AbstractGray - grey = round(UInt8, float(z) * 255) + grey = round.(UInt8, float(z) * 255) rgba = map(c -> UInt32( 0xff000000 + Int(c)<<16 + Int(c)<<8 + Int(c) ), grey) else rgba = map(c -> UInt32( round(Int, alpha(c) * 255) << 24 + From 32baaea5cb55bca2716b936946d587bee2e27bfe Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Sat, 13 Jan 2018 11:20:33 -0500 Subject: [PATCH 559/720] Check if any of the iterator args are zero Fixes #1329 --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 6b2fb689..bafbad93 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -199,7 +199,7 @@ allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:i function Base.start(itr::SegmentsIterator) nextidx = 1 - if anynan(1, itr.args) + if !any(iszero,map(length,itr.args)) && anynan(1, itr.args) _, nextidx = next(itr, 1) end nextidx From cf6c16102bc66388df527a3b3c77472e7758691c Mon Sep 17 00:00:00 2001 From: Will Kearney Date: Sat, 13 Jan 2018 13:57:03 -0500 Subject: [PATCH 560/720] Use isempty rather than iszero --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index bafbad93..0600821e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -199,7 +199,7 @@ allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:i function Base.start(itr::SegmentsIterator) nextidx = 1 - if !any(iszero,map(length,itr.args)) && anynan(1, itr.args) + if !any(isempty,itr.args) && anynan(1, itr.args) _, nextidx = next(itr, 1) end nextidx From 10a852080566bab4b773ab475caab4ef8ed554fe Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 31 Dec 2017 09:56:57 -0800 Subject: [PATCH 561/720] Add subplot labeling via annotations. --- src/args.jl | 8 +++---- src/backends/gr.jl | 2 +- src/backends/pgfplots.jl | 2 +- src/backends/plotly.jl | 5 +++-- src/backends/pyplot.jl | 2 +- src/components.jl | 48 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 57 insertions(+), 10 deletions(-) diff --git a/src/args.jl b/src/args.jl index e2586610..63b90848 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1294,11 +1294,9 @@ end function _update_subplot_periphery(sp::Subplot, anns::AVec) # extend annotations, and ensure we always have a (x,y,PlotText) tuple - newanns = vcat(anns, sp[:annotations]) - for (i,ann) in enumerate(newanns) - x,y,tmp = ann - ptxt = isa(tmp, PlotText) ? tmp : text(tmp) - newanns[i] = (x,y,ptxt) + newanns = [] + for ann in vcat(anns, sp[:annotations]) + append!(newanns, process_annotation(sp, ann...)) end sp.attr[:annotations] = newanns diff --git a/src/backends/gr.jl b/src/backends/gr.jl index c499a8ad..144880cd 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1330,7 +1330,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end end for ann in sp[:annotations] - x, y, val = ann + x, y, val = locate_annotation(sp, ann...) x, y = if is3d(sp) # GR.wc3towc(x, y, z) else diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index db4e8b26..1956f1b3 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -465,7 +465,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # add the annotations for ann in sp[:annotations] - pgf_add_annotation!(o,ann...) + pgf_add_annotation!(o, locate_annotation(sp, ann...)...) end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 5b4dcd8d..92a25809 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -385,8 +385,9 @@ function plotly_layout(plt::Plot) end # annotations - append!(d_out[:annotations], KW[plotly_annotation_dict(ann...; xref = "x$spidx", yref = "y$spidx") for ann in sp[:annotations]]) - + for ann in sp[:annotations] + append!(d_out[:annotations], KW[plotly_annotation_dict(locate_annotation(sp, ann...)...; xref = "x$spidx", yref = "y$spidx")]) + end # series_annotations for series in series_list(sp) anns = series[:series_annotations] diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d2566d44..8630c931 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -969,7 +969,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # add the annotations for ann in sp[:annotations] - py_add_annotations(sp, ann...) + py_add_annotations(sp, locate_annotation(sp, ann...)...) end # title diff --git a/src/components.jl b/src/components.jl index 7f452b97..20acffc5 100644 --- a/src/components.jl +++ b/src/components.jl @@ -348,6 +348,7 @@ PlotText(str) = PlotText(string(str), font()) Create a PlotText object wrapping a string with font info, for plot annotations """ text(t::PlotText) = t +text(t::PlotText, font::Font) = PlotText(t.str, font) text(str::AbstractString, f::Font) = PlotText(str, f) function text(str, args...) PlotText(string(str), font(args...)) @@ -535,6 +536,53 @@ annotations(anns::AVec) = anns annotations(anns) = Any[anns] annotations(sa::SeriesAnnotations) = sa +# Expand arrays of coordinates, positions and labels into induvidual annotations +# and make sure labels are of type PlotText +function process_annotation(sp::Subplot, xs, ys, labs, font = font()) + anns = [] + labs = makevec(labs) + for i in 1:max(length(xs), length(ys), length(labs)) + x, y, lab = _cycle(xs, i), _cycle(ys, i), _cycle(labs, i) + if lab == :auto + alphabet = "abcdefghijklmnopqrstuvwxyz" + push!(anns, (x, y, text(string("(", alphabet[sp[:subplot_index]], ")"), font))) + else + push!(anns, (x, y, isa(lab, PlotText) ? lab : text(lab, font))) + end + end + anns +end +function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, labs, font = font()) + anns = [] + positions, labs = makevec(positions), makevec(labs) + for i in 1:max(length(positions), length(labs)) + pos, lab = _cycle(positions, i), _cycle(labs, i) + if lab == :auto + alphabet = "abcdefghijklmnopqrstuvwxyz" + push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font))) + else + push!(anns, (pos, isa(lab, PlotText) ? lab : text(lab, font))) + end + end + anns +end + +# Give each annotation coordinates based on specified position +function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText) + position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}( + :top_left => (0.1, 0.9), + :top_center => (0.5, 0.9), + :top_right => (0.9, 0.9), + :bottom_right => (0.9, 0.1), + :bottom_left => (0.1, 0.9), + :bottom_center => (0.5,0.1), + ) + xmin, xmax = ignorenan_extrema(sp[:xaxis]) + ymin, ymax = ignorenan_extrema(sp[:yaxis]) + x, y = (xmin, ymin).+ position_multiplier[pos].* (xmax - xmin, ymax - ymin) + (x, y, lab) +end +locate_annotation(sp::Subplot, x, y, label::PlotText) = (x, y, label) # ----------------------------------------------------------------------- "type which represents z-values for colors and sizes (and anything else that might come up)" From d79c66e5b6604644629348e263fa91d5030cc9a4 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 14 Jan 2018 11:45:31 +0000 Subject: [PATCH 562/720] Add position aliases. --- src/args.jl | 15 +++++++++++++++ src/components.jl | 13 +++++++------ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/args.jl b/src/args.jl index 63b90848..808822b3 100644 --- a/src/args.jl +++ b/src/args.jl @@ -159,6 +159,21 @@ const _markerAliases = Dict{Symbol,Symbol}( :spike => :vline, ) +const _positionAliases = Dict{Symbol,Symbol}( + :top_left => :topleft, + :tl => :topleft, + :top_center => :topcenter, + :tc => :topcenter, + :top_right => :topright, + :tr => :topright, + :bottom_left => :bottomleft, + :bl => :bottomleft, + :bottom_center => :bottomcenter, + :bc => :bottomcenter, + :bottom_right => :bottomright, + :br => :bottomright, +) + const _allScales = [:identity, :ln, :log2, :log10, :asinh, :sqrt] const _logScales = [:ln, :log2, :log10] const _logScaleBases = Dict(:ln => e, :log2 => 2.0, :log10 => 10.0) diff --git a/src/components.jl b/src/components.jl index 20acffc5..2b1284ce 100644 --- a/src/components.jl +++ b/src/components.jl @@ -557,6 +557,7 @@ function process_annotation(sp::Subplot, positions::Union{AVec{Symbol},Symbol}, positions, labs = makevec(positions), makevec(labs) for i in 1:max(length(positions), length(labs)) pos, lab = _cycle(positions, i), _cycle(labs, i) + pos = get(_positionAliases, pos, pos) if lab == :auto alphabet = "abcdefghijklmnopqrstuvwxyz" push!(anns, (pos, text(string("(", alphabet[sp[:subplot_index]], ")"), font))) @@ -570,12 +571,12 @@ end # Give each annotation coordinates based on specified position function locate_annotation(sp::Subplot, pos::Symbol, lab::PlotText) position_multiplier = Dict{Symbol, Tuple{Float64,Float64}}( - :top_left => (0.1, 0.9), - :top_center => (0.5, 0.9), - :top_right => (0.9, 0.9), - :bottom_right => (0.9, 0.1), - :bottom_left => (0.1, 0.9), - :bottom_center => (0.5,0.1), + :topleft => (0.1, 0.9), + :topcenter => (0.5, 0.9), + :topright => (0.9, 0.9), + :bottomleft => (0.1, 0.1), + :bottomcenter => (0.5, 0.1), + :bottomright => (0.9, 0.1), ) xmin, xmax = ignorenan_extrema(sp[:xaxis]) ymin, ymax = ignorenan_extrema(sp[:yaxis]) From 11ef2be5063734db5e1a2e5e70b1f064455a23ca Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 17 Jan 2018 15:18:36 +0100 Subject: [PATCH 563/720] update pyart3D --- src/backends/pyplot.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 8630c931..de899a3c 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -83,7 +83,6 @@ function _initialize_backend(::PyPlotBackend) export PyPlot const pycolors = PyPlot.pyimport("matplotlib.colors") const pypath = PyPlot.pyimport("matplotlib.path") - const mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d") const pypatches = PyPlot.pyimport("matplotlib.patches") const pyfont = PyPlot.pyimport("matplotlib.font_manager") const pyticker = PyPlot.pyimport("matplotlib.ticker") @@ -92,7 +91,7 @@ function _initialize_backend(::PyPlotBackend) pynp["seterr"](invalid="ignore") const pytransforms = PyPlot.pyimport("matplotlib.transforms") const pycollections = PyPlot.pyimport("matplotlib.collections") - const pyart3d = PyPlot.pyimport("mpl_toolkits.mplot3d.art3d") + const pyart3d = PyPlot.art3D # "support" matplotlib v1.5 const set_facecolor_sym = if PyPlot.version < v"2" From 5e1c67c042f491955b2d0cd6d060d18fc04a6eca Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 18 Jan 2018 10:44:35 +0100 Subject: [PATCH 564/720] fix grouping of series_annotations --- src/series.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/series.jl b/src/series.jl index 10cc99bb..e545d485 100644 --- a/src/series.jl +++ b/src/series.jl @@ -548,9 +548,14 @@ end splittable_kw(key, val, lengthGroup) = false splittable_kw(key, val::AbstractArray, lengthGroup) = (key != :group) && size(val,1) == lengthGroup splittable_kw(key, val::Tuple, lengthGroup) = all(splittable_kw.(key, val, lengthGroup)) +splittable_kw(key, val::SeriesAnnotations, lengthGroup) = splittable_kw(key, val.strs, lengthGroup) split_kw(key, val::AbstractArray, indices) = val[indices, fill(Colon(), ndims(val)-1)...] split_kw(key, val::Tuple, indices) = Tuple(split_kw(key, v, indices) for v in val) +function split_kw(key, val::SeriesAnnotations, indices) + split_strs = split_kw(key, val.strs, indices) + return SeriesAnnotations(split_strs, val.font, val.baseshape, val.scalefactor) +end function groupedvec2mat(x_ind, x, y::AbstractArray, groupby, def_val = y[1]) y_mat = Array{promote_type(eltype(y), typeof(def_val))}(length(keys(x_ind)), length(groupby.groupLabels)) From 99f3b7ae99972085038321710778e810b65b2f43 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 18 Jan 2018 16:21:46 +0000 Subject: [PATCH 565/720] Fix axis limits for images. --- src/pipeline.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index 8dc475cb..e05f7791 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -357,9 +357,9 @@ end function _expand_subplot_extrema(sp::Subplot, d::KW, st::Symbol) # adjust extrema and discrete info if st == :image - w, h = size(d[:z]) - expand_extrema!(sp[:xaxis], (0,w)) - expand_extrema!(sp[:yaxis], (0,h)) + xmin, xmax = ignorenan_extrema(d[:x]); ymin, ymax = ignorenan_extrema(d[:y]) + expand_extrema!(sp[:xaxis], (xmin, xmax)) + expand_extrema!(sp[:yaxis], (ymin, ymax)) sp[:yaxis].d[:flip] = true elseif !(st in (:pie, :histogram, :bins2d, :histogram2d)) expand_extrema!(sp, d) From d4075a1ef5ab99b0b1fb29cfd27cd8ec9906da5e Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 18 Jan 2018 16:22:49 +0000 Subject: [PATCH 566/720] Allow movement and resizing of images. --- src/backends/glvisualize.jl | 2 +- src/backends/gr.jl | 3 ++- src/backends/pyplot.jl | 4 +++- src/series.jl | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index 8861fa46..b0841596 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -1215,7 +1215,7 @@ end function gl_image(img, kw_args) rect = kw_args[:primitive] - kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(rect.x, rect.y, rect.h, rect.w) # seems to be flipped + kw_args[:primitive] = GeometryTypes.SimpleRectangle{Float32}(rect.x, rect.y, rect.w, rect.h) visualize(img, Style(:default), kw_args) end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 1ef54d63..89c3c355 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1199,6 +1199,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :image z = transpose_z(series, series[:z].surf, true)' w, h = size(z) + xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y]) if eltype(z) <: Colors.AbstractGray grey = round.(UInt8, float(z) * 255) rgba = map(c -> UInt32( 0xff000000 + Int(c)<<16 + Int(c)<<8 + Int(c) ), grey) @@ -1208,7 +1209,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) round(Int, green(c) * 255) << 8 + round(Int, red(c) * 255) ), z) end - GR.drawimage(0, w, h, 0, w, h, rgba) + GR.drawimage(xmin, xmax, ymax, ymin, w, h, rgba) end # this is all we need to add the series_annotations text diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index de899a3c..f3823e0a 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -731,6 +731,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st == :image # @show typeof(z) + xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y]) img = Array(transpose_z(series, z.surf)) z = if eltype(img) <: Colors.AbstractGray float(img) @@ -743,7 +744,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], cmap = py_colormap([:black, :white]), vmin = 0.0, - vmax = 1.0 + vmax = 1.0, + extent = (xmin, xmax, ymax, ymin) ) push!(handles, handle) diff --git a/src/series.jl b/src/series.jl index e545d485..a727844c 100644 --- a/src/series.jl +++ b/src/series.jl @@ -325,6 +325,7 @@ end else seriestype := :heatmap yflip --> true + cbar --> false fillcolor --> ColorGradient([:black, :white]) SliceIt, 1:m, 1:n, Surface(convert(Matrix{Float64}, mat)) end @@ -341,6 +342,7 @@ end else seriestype := :heatmap yflip --> true + cbar --> false z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat) SliceIt, 1:m, 1:n, Surface(z) end @@ -465,6 +467,36 @@ end SliceIt, x, y, Surface(z) end +# # images - grays + +@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Gray + if is_seriestype_supported(:image) + seriestype := :image + SliceIt, x, y, Surface(mat) + else + seriestype := :heatmap + yflip --> true + cbar --> false + fillcolor --> ColorGradient([:black, :white]) + SliceIt, x, y, Surface(convert(Matrix{Float64}, mat)) + end +end + +# # images - colors + +@recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Colorant + if is_seriestype_supported(:image) + seriestype := :image + SliceIt, x, y, Surface(mat) + else + seriestype := :heatmap + yflip --> true + cbar --> false + z, plotattributes[:fillcolor] = replace_image_with_heatmap(mat) + SliceIt, x, y, Surface(z) + end +end + # # # # -------------------------------------------------------------------- From a79a40b1e8b79162f7cf1c429207b703a7694d5a Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 18 Jan 2018 18:21:26 +0000 Subject: [PATCH 567/720] Allow manual flipping of yaxis for images. --- src/pipeline.jl | 1 - src/series.jl | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/pipeline.jl b/src/pipeline.jl index e05f7791..931aa76e 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -360,7 +360,6 @@ function _expand_subplot_extrema(sp::Subplot, d::KW, st::Symbol) xmin, xmax = ignorenan_extrema(d[:x]); ymin, ymax = ignorenan_extrema(d[:y]) expand_extrema!(sp[:xaxis], (xmin, xmax)) expand_extrema!(sp[:yaxis], (ymin, ymax)) - sp[:yaxis].d[:flip] = true elseif !(st in (:pie, :histogram, :bins2d, :histogram2d)) expand_extrema!(sp, d) end diff --git a/src/series.jl b/src/series.jl index a727844c..1a502cc5 100644 --- a/src/series.jl +++ b/src/series.jl @@ -321,6 +321,7 @@ end n, m = size(mat) if is_seriestype_supported(:image) seriestype := :image + yflip --> true SliceIt, 1:m, 1:n, Surface(mat) else seriestype := :heatmap @@ -338,6 +339,7 @@ end if is_seriestype_supported(:image) seriestype := :image + yflip --> true SliceIt, 1:m, 1:n, Surface(mat) else seriestype := :heatmap @@ -472,6 +474,7 @@ end @recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Gray if is_seriestype_supported(:image) seriestype := :image + yflip --> true SliceIt, x, y, Surface(mat) else seriestype := :heatmap @@ -487,6 +490,7 @@ end @recipe function f(x::AVec, y::AVec, mat::AMat{T}) where T<:Colorant if is_seriestype_supported(:image) seriestype := :image + yflip --> true SliceIt, x, y, Surface(mat) else seriestype := :heatmap From 11a856fbb3cacc1d72c46ae639a81c8b51cdf4c4 Mon Sep 17 00:00:00 2001 From: Graham A Smith Date: Wed, 31 Jan 2018 13:12:32 -0600 Subject: [PATCH 568/720] Allow animation frame saving frequency to be a variable. --- src/animation.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/animation.jl b/src/animation.jl index 93f28427..12fdb36b 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -115,6 +115,7 @@ function _animate(forloop::Expr, args...; callgif = false) # add the call to frame to the end of each iteration animsym = gensym("anim") countersym = gensym("counter") + freqassert = :() block = forloop.args[2] # create filter @@ -127,7 +128,7 @@ function _animate(forloop::Expr, args...; callgif = false) # filter every `freq` frames (starting with the first frame) @assert n == 2 freq = args[2] - @assert isa(freq, Integer) && freq > 0 + freqassert = :(@assert isa($freq, Integer) && $freq > 0) :(mod1($countersym, $freq) == 1) elseif args[1] == :when @@ -147,6 +148,7 @@ function _animate(forloop::Expr, args...; callgif = false) # full expression: esc(quote + $freqassert # if filtering, check frequency is an Integer > 0 $animsym = Animation() # init animation object $countersym = 1 # init iteration counter $forloop # for loop, saving a frame after each iteration From 18ea542cc4a261034ce45ca2020ecb70cad628ae Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 5 Feb 2018 09:21:06 -0800 Subject: [PATCH 569/720] Add GR to REQUIRE --- REQUIRE | 1 + 1 file changed, 1 insertion(+) diff --git a/REQUIRE b/REQUIRE index a99ac547..f0c12af5 100644 --- a/REQUIRE +++ b/REQUIRE @@ -13,3 +13,4 @@ JSON NaNMath Requires Contour +GR From 2004090ce58edb5c26f25a87f6a3e90390bee8fc Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Mon, 5 Feb 2018 12:34:39 -0800 Subject: [PATCH 570/720] Remove GR clone in travis tests --- test/travis_commands.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/travis_commands.jl b/test/travis_commands.jl index 4befaaef..91ab0ca6 100644 --- a/test/travis_commands.jl +++ b/test/travis_commands.jl @@ -1,8 +1,8 @@ Pkg.add("ImageMagick") Pkg.build("ImageMagick") -Pkg.clone("GR") -Pkg.build("GR") +# Pkg.clone("GR") +# Pkg.build("GR") Pkg.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git") From bde415edd79c5694d6c5243afc3f89ee623d2c9e Mon Sep 17 00:00:00 2001 From: MA Laforge Date: Tue, 6 Feb 2018 06:26:07 -0500 Subject: [PATCH 571/720] Add support for Surface plots. --- src/backends/hdf5.jl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index 2e677625..2cbe7a76 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -167,6 +167,7 @@ function _initialize_backend(::HDF5Backend) # "PLOTTEXT" => PlotText, "COLORGRADIENT" => ColorGradient, "AXIS" => Axis, + "SURFACE" => Surface, "SUBPLOT" => Subplot, "NULLABLE" => Nullable, ) @@ -407,6 +408,11 @@ function _hdf5plot_gwrite(grp, k::String, v::Axis) _hdf5plot_writetype(grp, Axis) return end +function _hdf5plot_gwrite(grp, k::String, v::Surface) + grp = HDF5.g_create(grp, k) + _hdf5plot_gwrite(grp, "data2d", v.surf) + _hdf5plot_writetype(grp, Surface) +end #TODO: "Properly" support Nullable using _hdf5plot_writetype? function _hdf5plot_gwrite(grp, k::String, v::Nullable) if isnull(v) @@ -577,6 +583,11 @@ function _hdf5plot_read(grp, k::String, T::Type{Axis}, dtid) _hdf5plot_read(grp, kwlist) return Axis([], kwlist) end +function _hdf5plot_read(grp, k::String, T::Type{Surface}, dtid) + grp = HDF5.g_open(grp, k) + data2d = _hdf5plot_read(grp, "data2d") + return Surface(data2d) +end function _hdf5plot_read(grp, k::String, T::Type{Subplot}, dtid) grp = HDF5.g_open(grp, k) idx = _hdf5plot_read(grp, "index") From e19e25473ce22407aa08a866ae888489eef41e40 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 11 Feb 2018 10:36:12 +0000 Subject: [PATCH 572/720] Fix misplaced Plotly annotations. --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 92a25809..0330e149 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -147,7 +147,7 @@ function plotly_annotation_dict(x, y, val; xref="paper", yref="paper") :text => val, :xref => xref, :x => x, - :yref => xref, + :yref => yref, :y => y, :showarrow => false, ) From 82ceb71bd00d04a26470fc34ade1a7156ffa0ca5 Mon Sep 17 00:00:00 2001 From: mats cronqvist Date: Fri, 16 Feb 2018 14:46:45 +0100 Subject: [PATCH 573/720] fix IJulia integration --- src/output.jl | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/output.jl b/src/output.jl index 88caeeee..c06e0be9 100644 --- a/src/output.jl +++ b/src/output.jl @@ -256,20 +256,23 @@ end # IJulia # --------------------------------------------------------- -const _ijulia_output = String["text/html"] - @require IJulia begin if IJulia.inited - export set_ijulia_output - function set_ijulia_output(mimestr::AbstractString) - # info("Setting IJulia output format to $mimestr") - global _ijulia_output - _ijulia_output[1] = mimestr - end function IJulia.display_dict(plt::Plot) - global _ijulia_output - Dict{String, String}(_ijulia_output[1] => sprint(show, _ijulia_output[1], plt)) + output_type = Symbol(plt.attr[:html_output_format]) + if output_type == :auto + output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) + end + if output_type == :png + mime = "image/png" + Dict{String,String}(mime => base64encode(show, MIME(mime), plt)) + elseif output_type == :svg + mime = "image/svg+xml" + Dict{String,String}(mime => sprint(show, MIME(mime), plt)) + else + error("Unsupported output type $output_type") + end end # default text/plain passes to html... handles Interact issues @@ -278,7 +281,6 @@ const _ijulia_output = String["text/html"] end ENV["MPLBACKEND"] = "Agg" - set_ijulia_output("text/html") end end From 5ba4c10a18de71cd86a93175539687e44678826f Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 17 Feb 2018 17:32:53 +0000 Subject: [PATCH 574/720] Prevent addition of curly braces around style string. --- 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 1956f1b3..c1100932 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -450,7 +450,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) end @label colorbar_end - o = axisf(; style = style, kw...) + o = axisf(; style = join(style, ","), kw...) # add the series object to the PGFPlots.Axis for series in series_list(sp) From c0248069a1b250b23d4a244b7eb3adf07fef26ca Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 17 Feb 2018 23:33:55 +0100 Subject: [PATCH 575/720] add Dates.Time recipe --- src/recipes.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 8c669a78..64d6e48b 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -1000,13 +1000,15 @@ abline!(args...; kw...) = abline!(current(), args...; kw...) # ------------------------------------------------- -# Dates +# Dates & Times dateformatter(dt) = string(Date(Dates.UTD(dt))) datetimeformatter(dt) = string(DateTime(Dates.UTM(dt))) +timeformatter(t) = string(Dates.Time(Dates.Nanosecond(t))) @recipe f(::Type{Date}, dt::Date) = (dt -> Dates.value(dt), dateformatter) @recipe f(::Type{DateTime}, dt::DateTime) = (dt -> Dates.value(dt), datetimeformatter) +@recipe f(::Type{Dates.Time}, t::Dates.Time) = (t -> Dates.value(t), timeformatter) # ------------------------------------------------- # Complex Numbers From 9e2264c841afa0371e074012a51eabfa3392d9c4 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Feb 2018 22:49:27 +0100 Subject: [PATCH 576/720] consider fillrange in step recipes --- src/recipes.jl | 29 +++++++++++++++++++++++++++-- src/utils.jl | 2 +- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 8c669a78..a94f5ec4 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -140,11 +140,32 @@ function make_steps(x, y, st) newx, newy end +make_steps(x, st) = x +function make_steps(x::AbstractArray, st) + n = length(x) + n == 0 && return zeros(0) + newx = zeros(2n - 1) + for i in 1:n + idx = 2i - 1 + newx[idx] = x[i] + if i > 1 + newx[idx - 1] = x[st == :pre ? i : i - 1] + end + end + return newx +end +make_steps(t::Tuple, st) = Tuple(make_steps(ti, st) for ti in t) + + # create a path from steps @recipe function f(::Type{Val{:steppre}}, x, y, z) - plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppre) + plotattributes[:x] = make_steps(x, :post) + plotattributes[:y] = make_steps(y, :pre) seriestype := :path + # handle fillrange + plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :pre) + # create a secondary series for the markers if plotattributes[:markershape] != :none @series begin @@ -163,9 +184,13 @@ end # create a path from steps @recipe function f(::Type{Val{:steppost}}, x, y, z) - plotattributes[:x], plotattributes[:y] = make_steps(x, y, :steppost) + plotattributes[:x] = make_steps(x, :pre) + plotattributes[:y] = make_steps(y, :post) seriestype := :path + # handle fillrange + plotattributes[:fillrange] = make_steps(plotattributes[:fillrange], :post) + # create a secondary series for the markers if plotattributes[:markershape] != :none @series begin diff --git a/src/utils.jl b/src/utils.jl index 0600821e..3544ead9 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1051,7 +1051,7 @@ guidefont(ax::Axis) = font( # --------------------------------------------------------------- # converts unicode scientific notation unsupported by pgfplots and gr -# into a format that works +# into a format that works function convert_sci_unicode(label::AbstractString) unicode_dict = Dict( From 6c13d87a00e439265e17a03bee09772d8736ca9c Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Feb 2018 22:59:37 +0100 Subject: [PATCH 577/720] remove old make_steps function --- src/recipes.jl | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index a94f5ec4..bb297029 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -124,22 +124,6 @@ end # --------------------------------------------------------------------------- # steps -function make_steps(x, y, st) - n = length(x) - n == 0 && return zeros(0),zeros(0) - newx, newy = zeros(2n-1), zeros(2n-1) - for i=1:n - idx = 2i-1 - newx[idx] = x[i] - newy[idx] = y[i] - if i > 1 - newx[idx-1] = x[st == :steppre ? i-1 : i] - newy[idx-1] = y[st == :steppre ? i : i-1] - end - end - newx, newy -end - make_steps(x, st) = x function make_steps(x::AbstractArray, st) n = length(x) From 06466b060f912ad9b51257f330ef2d9b287467c1 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Wed, 21 Feb 2018 10:09:57 +0000 Subject: [PATCH 578/720] Implement :native ticks option. --- src/axes.jl | 3 +++ src/backends/gr.jl | 6 +++--- src/backends/pgfplots.jl | 2 +- src/backends/plotly.jl | 4 ++-- src/backends/pyplot.jl | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index d62667fb..855f8d97 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -234,6 +234,9 @@ function get_ticks(axis::Axis) ticks = _transform_ticks(axis[:ticks]) ticks in (nothing, false) && return nothing + # treat :native ticks as :auto + ticks = ticks == :native ? :auto : ticks + dvals = axis[:discrete_values] cv, dv = if !isempty(dvals) && ticks == :auto # discrete ticks... diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 89c3c355..90e2a5a6 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -222,7 +222,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) - if yaxis[:formatter] == :scientific && yaxis[:ticks] == :auto + if yaxis[:formatter] == :scientific && yaxis[:ticks] in (:auto, :native) rtick_labels = convert_sci_unicode(rtick_labels) end @@ -884,7 +884,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin) # @show cv dv ymin xi yi flip mirror (flip $ mirror) - if xaxis[:ticks] == :auto + if xaxis[:ticks] in (:auto, :native) # ensure correct dispatch in gr_text for automatic log ticks if xaxis[:scale] in _logScales dv = string(dv, "\\ ") @@ -903,7 +903,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # use xor ($) to get the right y coords xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv) # @show cv dv xmin xi yi - if yaxis[:ticks] == :auto + if yaxis[:ticks] in (:auto, :native) # ensure correct dispatch in gr_text for automatic log ticks if yaxis[:scale] in _logScales dv = string(dv, "\\ ") diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 1956f1b3..d22b5b1a 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -314,7 +314,7 @@ function pgf_axis(sp::Subplot, letter) kw[Symbol(letter,:max)] = lims[2] end - if !(axis[:ticks] in (nothing, false, :none)) && framestyle != :none + if !(axis[:ticks] in (nothing, false, :none, :native)) && framestyle != :none ticks = get_ticks(axis) #pgf plot ignores ticks with angle below 90 when xmin = 90 so shift values tick_values = ispolar(sp) && letter == :x ? [rad2deg.(ticks[1])[3:end]..., 360, 405] : ticks[1] diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 0330e149..014d7b21 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -273,8 +273,8 @@ function plotly_axis(axis::Axis, sp::Subplot) end # ticks - ticks = get_ticks(axis) - if ticks != :auto + if axis[:ticks] != :native + ticks = get_ticks(axis) ttype = ticksType(ticks) if ttype == :ticks ax[:tickmode] = "array" diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index f3823e0a..4801e38e 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1069,7 +1069,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if sp[:framestyle] == :origin && length(ticks) > 1 ticks[2][ticks[1] .== 0] = "" end - py_set_ticks(ax, ticks, letter) + axis[:ticks] != :native ? py_set_ticks(ax, ticks, letter) : nothing pyaxis[:set_tick_params](direction = axis[:tick_direction] == :out ? "out" : "in") ax[Symbol("set_", letter, "label")](axis[:guide]) if get(axis.d, :flip, false) From 94863d69b1ce4423f39e59516bf68be889e2c6d1 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Wed, 21 Feb 2018 10:17:13 +0000 Subject: [PATCH 579/720] Consider all ticks = false aliases in backends. --- src/backends/gr.jl | 4 ++-- src/backends/pgfplots.jl | 2 +- src/backends/plotly.jl | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 90e2a5a6..e49dd6b2 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -649,7 +649,7 @@ function _update_min_padding!(sp::Subplot{GRBackend}) end # Add margin for x and y ticks xticks, yticks = axis_drawing_info(sp)[1:2] - if !(xticks in (nothing, false)) + if !(xticks in (nothing, false, :none)) flip, mirror = gr_set_xticks_font(sp) l = gr_get_ticks_size(xticks, 2) if mirror @@ -658,7 +658,7 @@ function _update_min_padding!(sp::Subplot{GRBackend}) bottompad += 1mm + gr_plot_size[2] * l * px end end - if !(yticks in (nothing, false)) + if !(yticks in (nothing, false, :none)) flip, mirror = gr_set_yticks_font(sp) l = gr_get_ticks_size(yticks, 1) if mirror diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index d22b5b1a..4d8ef623 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -295,7 +295,7 @@ function pgf_axis(sp::Subplot, letter) end # ticks on or off - if axis[:ticks] in (nothing, false) || framestyle == :none + if axis[:ticks] in (nothing, false, :none) || framestyle == :none push!(style, "$(letter)majorticks=false") end diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 014d7b21..c76c356f 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -260,7 +260,7 @@ function plotly_axis(axis::Axis, sp::Subplot) lims = axis_limits(axis) ax[:range] = map(scalefunc(axis[:scale]), lims) - if !(axis[:ticks] in (nothing, :none)) + if !(axis[:ticks] in (nothing, :none, false)) ax[:titlefont] = plotly_font(guidefont(axis)) ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(tickfont(axis)) From 5017024557dfe05b38e20abdc176775e13bfbc8e Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Wed, 21 Feb 2018 14:50:32 +0000 Subject: [PATCH 580/720] Fix handling of discrete values with ticks = :native for Plotly. --- src/backends/plotly.jl | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index c76c356f..0b95850c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -258,7 +258,7 @@ function plotly_axis(axis::Axis, sp::Subplot) ax[:tickangle] = -axis[:rotation] lims = axis_limits(axis) - ax[:range] = map(scalefunc(axis[:scale]), lims) + axis[:ticks] != :native ? ax[:range] = map(scalefunc(axis[:scale]), lims) : nothing if !(axis[:ticks] in (nothing, :none, false)) ax[:titlefont] = plotly_font(guidefont(axis)) @@ -465,7 +465,7 @@ function plotly_close_shapes(x, y) nanvcat(xs), nanvcat(ys) end -plotly_data(v) = collect(v) +plotly_data(v) = v != nothing ? collect(v) : v plotly_data(surf::Surface) = surf.surf plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v) @@ -493,7 +493,16 @@ function plotly_series(plt::Plot, series::Series) d_out[:yaxis] = "y$spidx" d_out[:showlegend] = should_add_to_legend(series) - x, y = plotly_data(series[:x]), plotly_data(series[:y]) + + x, y, z = map(letter -> (axis = sp[Symbol(letter, :axis)]; + if axis[:ticks] == :native && !isempty(axis[:discrete_values]) + axis[:discrete_values] + elseif st in (:heatmap, :contour, :surface, :wireframe) + plotly_surface_data(series, series[letter]) + else + plotly_data(series[letter]) + end), (:x, :y, :z)) + d_out[:name] = series[:label] isscatter = st in (:scatter, :scatter3d, :scattergl) @@ -502,13 +511,6 @@ function plotly_series(plt::Plot, series::Series) hasfillrange = st in (:path, :scatter, :scattergl) && (isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple)) - # for surface types, set the data - if st in (:heatmap, :contour, :surface, :wireframe) - for letter in [:x,:y,:z] - d_out[letter] = plotly_surface_data(series, series[letter]) - end - end - d_out[:colorbar] = KW(:title => sp[:colorbar_title]) clims = sp[:clims] @@ -548,13 +550,13 @@ function plotly_series(plt::Plot, series::Series) elseif st == :heatmap d_out[:type] = "heatmap" - # d_out[:x], d_out[:y], d_out[:z] = series[:x], series[:y], transpose_z(series, series[:z].surf, false) + d_out[:x], d_out[:y], d_out[:z] = x, y, z d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) d_out[:showscale] = hascolorbar(sp) elseif st == :contour d_out[:type] = "contour" - # d_out[:x], d_out[:y], d_out[:z] = series[:x], series[:y], transpose_z(series, series[:z].surf, false) + d_out[:x], d_out[:y], d_out[:z] = x, y, z # d_out[:showscale] = series[:colorbar] != :none d_out[:ncontours] = series[:levels] d_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines") @@ -563,7 +565,7 @@ function plotly_series(plt::Plot, series::Series) elseif st in (:surface, :wireframe) d_out[:type] = "surface" - # d_out[:x], d_out[:y], d_out[:z] = series[:x], series[:y], transpose_z(series, series[:z].surf, false) + d_out[:x], d_out[:y], d_out[:z] = x, y, z if st == :wireframe d_out[:hidesurface] = true wirelines = KW( @@ -595,8 +597,7 @@ function plotly_series(plt::Plot, series::Series) else hasline ? "lines" : "none" end - d_out[:x], d_out[:y] = x, y - d_out[:z] = plotly_data(series[:z]) + d_out[:x], d_out[:y], d_out[:z] = x, y, z else warn("Plotly: seriestype $st isn't supported.") From 0db60348aa507cdbb9bfdf5cd93f0cbf64d5a881 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 21 Feb 2018 17:03:23 +0100 Subject: [PATCH 581/720] reduce pyplot colorbar size for z values with very small or big absolute values --- src/backends/pyplot.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index f3823e0a..b496dbb2 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1295,7 +1295,8 @@ function _update_plot_object(plt::Plot{PyPlotBackend}) if haskey(sp.attr, :cbar_ax) cbw = sp.attr[:cbar_width] # this is the bounding box of just the colors of the colorbar (not labels) - has_toplabel = sp[:zaxis][:extrema].emax >= 1e7 + ex = sp[:zaxis][:extrema] + has_toplabel = !(1e-7 < max(abs(ex.emax), abs(ex.emin)) < 1e7) cb_bbox = BoundingBox(right(sp.bbox)-cbw+1mm, top(sp.bbox) + (has_toplabel ? 4mm : 2mm), _cbar_width-1mm, height(sp.bbox) - (has_toplabel ? 6mm : 4mm)) pcts = bbox_to_pcts(cb_bbox, figw, figh) sp.attr[:cbar_ax][:set_position](pcts) From de51beebe86c4ff8787d2f0741244184b03a13b6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 21 Feb 2018 17:47:11 +0100 Subject: [PATCH 582/720] ensure non-unique clims --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 3544ead9..e880ae62 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -568,7 +568,7 @@ function get_clims(sp::Subplot) isfinite(clims[1]) && (zmin = clims[1]) isfinite(clims[2]) && (zmax = clims[2]) end - return zmin < zmax ? (zmin, zmax) : (0.0, 0.0) + return zmin < zmax ? (zmin, zmax) : (-0.1, 0.1) end _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) From 1d51982cb0d343dc3897f32ef50631772f7fadaf Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Fri, 23 Feb 2018 10:56:57 +0000 Subject: [PATCH 583/720] Fix non-native lims for ticks = :native on PyPlot. --- 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 4801e38e..4d52fd43 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1060,7 +1060,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) pyaxis[Symbol(:tick_, pos)]() # the tick labels end py_set_scale(ax, axis) - py_set_lims(ax, axis) + axis[:ticks] != :native ? py_set_lims(ax, axis) : nothing if ispolar(sp) && letter == :y ax[:set_rlabel_position](90) end From b9d586c00969ade23157e72f87678b9eca258bcd Mon Sep 17 00:00:00 2001 From: piever Date: Sat, 24 Feb 2018 01:35:30 +0000 Subject: [PATCH 584/720] make plotlyjs use html in ijulia --- src/output.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index c06e0be9..48380006 100644 --- a/src/output.jl +++ b/src/output.jl @@ -171,7 +171,8 @@ const _mimeformats = Dict( const _best_html_output_type = KW( :pyplot => :png, :unicodeplots => :txt, - :glvisualize => :png + :glvisualize => :png, + :plotlyjs => :html ) # a backup for html... passes to svg or png depending on the html_output_format arg @@ -270,6 +271,9 @@ end elseif output_type == :svg mime = "image/svg+xml" Dict{String,String}(mime => sprint(show, MIME(mime), plt)) + elseif output_type == :html + mime = "text/html" + Dict{String,String}(mime => sprint(show, MIME(mime), plt)) else error("Unsupported output type $output_type") end From ef48b66ac4d0705f4f13e23e5d4e8f26904a50b9 Mon Sep 17 00:00:00 2001 From: piever Date: Sat, 24 Feb 2018 01:55:59 +0000 Subject: [PATCH 585/720] fix plotly --- src/backends/plotly.jl | 5 +++++ src/output.jl | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 0330e149..34d43b9e 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -794,6 +794,11 @@ function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend}) write(io, html_head(plt) * html_body(plt)) end +function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) + prepare_output(plt) + write(io, html_head(plt) * html_body(plt)) +end + function _display(plt::Plot{PlotlyBackend}) standalone_html_window(plt) end diff --git a/src/output.jl b/src/output.jl index 48380006..99a55d50 100644 --- a/src/output.jl +++ b/src/output.jl @@ -172,7 +172,8 @@ const _best_html_output_type = KW( :pyplot => :png, :unicodeplots => :txt, :glvisualize => :png, - :plotlyjs => :html + :plotlyjs => :html, + :plotly => :html ) # a backup for html... passes to svg or png depending on the html_output_format arg From 77c2ee6782ac7d6daa086d99be1da6aabcd75d01 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 25 Feb 2018 09:52:26 +0100 Subject: [PATCH 586/720] replace hline and vline marker shapes with _ and | on pyplot --- src/backends/pyplot.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 3dda803d..f05a13f0 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -214,6 +214,8 @@ function py_marker(marker::Symbol) marker == :hexagon && return "h" marker == :octagon && return "8" marker == :pixel && return "," + marker == :hline && return "_" + marker == :vline && return "|" haskey(_shapes, marker) && return py_marker(_shapes[marker]) warn("Unknown marker $marker") @@ -571,7 +573,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :scatter3d, :steppre, :steppost, :bar) if series[:marker_z] == nothing - extrakw[:c] = py_color_fix(py_markercolor(series), x) + extrakw[:c] = series[:markershape] in (:+, :x, :hline, :vline) ? py_markerstrokecolor(series) : py_color_fix(py_markercolor(series), x) else extrakw[:c] = convert(Vector{Float64}, series[:marker_z]) extrakw[:cmap] = py_markercolormap(series) From a7a5fe36f9ed2a9ec0692d95c3d9156e09ec7617 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 26 Feb 2018 10:03:02 +0100 Subject: [PATCH 587/720] default to a bar width of _bar_width for bar plots with only one data point --- src/recipes.jl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index b7c80c5d..aa37ee5c 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -317,7 +317,11 @@ end # compute half-width of bars bw = plotattributes[:bar_width] hw = if bw == nothing - 0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx))) + if nx > 1 + 0.5*_bar_width*ignorenan_minimum(filter(x->x>0, diff(procx))) + else + 0.5 * _bar_width + end else Float64[0.5_cycle(bw,i) for i=1:length(procx)] end From f901254519a7ea202c7be032acd1aa0c16acee8b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 21:19:18 +0100 Subject: [PATCH 588/720] add contour_labels attribute and minor GR contour fixes --- src/arg_desc.jl | 1 + src/args.jl | 2 ++ src/backends/gr.jl | 12 ++++++++---- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 386639b6..199190db 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -43,6 +43,7 @@ const _arg_desc = KW( :normalize => "Bool or Symbol. Histogram normalization mode. Possible values are: false/:none (no normalization, default), true/:pdf (normalize to a discrete Probability Density Function, where the total area of the bins is 1), :probability (bin heights sum to 1) and :density (the area of each bin, rather than the height, is equal to the counts - useful for uneven bin sizes).", :weights => "AbstractVector. Used in histogram types for weighted counts.", :contours => "Bool. Add contours to the side-grids of 3D plots? Used in surface/wireframe.", +:contour_labels => "Bool. Show labels at the contour lines?", :match_dimensions => "Bool. For heatmap types... should the first dimension of a matrix (rows) correspond to the first dimension of the plot (x-axis)? The default is false, which matches the behavior of Matplotlib, Plotly, and others. Note: when passing a function for z, the function should still map `(x,y) -> z`.", :subplot => "Integer (subplot index) or Subplot object. The subplot that this series belongs to.", :series_annotations => "AbstractVector of String or PlotText. These are annotations which are mapped to data points/positions.", diff --git a/src/args.jl b/src/args.jl index 808822b3..0a06b64a 100644 --- a/src/args.jl +++ b/src/args.jl @@ -272,6 +272,7 @@ const _series_defaults = KW( :normalize => false, # do we want a normalized histogram? :weights => nothing, # optional weights for histograms (1D and 2D) :contours => false, # add contours to 3d surface and wireframe plots + :contour_labels => false, :match_dimensions => false, # do rows match x (true) or y (false) for heatmap/image/spy? see issue 196 # this ONLY effects whether or not the z-matrix is transposed for a heatmap display! :subplot => :auto, # which subplot(s) does this series belong to? @@ -574,6 +575,7 @@ add_aliases(:gridstyle, :grid_style, :gridlinestyle, :grid_linestyle, :grid_ls, add_aliases(:framestyle, :frame_style, :frame, :axesstyle, :axes_style, :boxstyle, :box_style, :box, :borderstyle, :border_style, :border) add_aliases(:tick_direction, :tickdirection, :tick_dir, :tickdir, :tick_orientation, :tickorientation, :tick_or, :tickor) add_aliases(:camera, :cam, :viewangle, :view_angle) +add_aliases(:contour_labels, :contourlabels, :clabels, :clabs) # add all pluralized forms to the _keyAliases dict for arg in keys(_series_defaults) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e49dd6b2..8d2d49da 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1055,24 +1055,28 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :contour zmin, zmax = clims GR.setspace(zmin, zmax, 0, 90) - if typeof(series[:levels]) <: Array + if typeof(series[:levels]) <: AbstractArray h = series[:levels] else - h = linspace(zmin, zmax, series[:levels]) + h = series[:levels] > 1 ? linspace(zmin, zmax, series[:levels]) : [(zmin + zmax) / 2] end if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else GR.setlinetype(gr_linetype[series[:linestyle]]) GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) - GR.contour(x, y, h, z, 1000) + if plot_color(series[:linecolor]) == plot_color(:black) + GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0)) + else + GR.contour(x, y, h, z, 1000 + (series[:contour_labels] == true ? 1 : 0)) + end end # create the colorbar of contour levels if cmap gr_set_line(1, :solid, yaxis[:foreground_color_axis]) gr_set_viewport_cmap(sp) - l = round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) + l = (length(h) > 1) ? round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) : 1000 GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) From 9c4cc5acda289926bf34f0d71a74d3fb121964d2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 21:27:34 +0100 Subject: [PATCH 589/720] GR colorbar fixees --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 8d2d49da..9aa375be 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1076,7 +1076,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if cmap gr_set_line(1, :solid, yaxis[:foreground_color_axis]) gr_set_viewport_cmap(sp) - l = (length(h) > 1) ? round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) : 1000 + l = (length(h) > 1) ? round.(Int32, 1000 + (h - ignorenan_minimum(h)) / (ignorenan_maximum(h) - ignorenan_minimum(h)) * 255) : Int32[1000, 1255] GR.setwindow(xmin, xmax, zmin, zmax) GR.cellarray(xmin, xmax, zmax, zmin, 1, length(l), l) ztick = 0.5 * GR.tick(zmin, zmax) From fdb2ee2847b91f6bfc9e68ee3b94894a6e17d2af Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 22:10:45 +0100 Subject: [PATCH 590/720] implement contour_labels for PyPlot and fix #1091 --- src/backends/gr.jl | 1 + src/backends/pyplot.jl | 4 ++++ src/utils.jl | 5 ++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 9aa375be..e320e8dd 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -45,6 +45,7 @@ const _gr_attr = merge_with_base_supported([ :framestyle, :tick_direction, :camera, + :contour_labels, ]) const _gr_seriestype = [ :path, :scatter, diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index f05a13f0..f5f60464 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -42,6 +42,7 @@ const _pyplot_attr = merge_with_base_supported([ :framestyle, :tick_direction, :camera, + :contour_labels, ]) const _pyplot_seriestype = [ :path, :steppre, :steppost, :shape, @@ -654,6 +655,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) cmap = py_linecolormap(series), extrakw... ) + if series[:contour_labels] == true + PyPlot.clabel(handle, handle[:levels]) + end push!(handles, handle) # contour fills diff --git a/src/utils.jl b/src/utils.jl index e880ae62..cdab41c6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -575,7 +575,10 @@ _update_clims(zmin, zmax, emin, emax) = min(zmin, emin), max(zmax, emax) function hascolorbar(series::Series) st = series[:seriestype] - hascbar = st in (:heatmap, :contour) + hascbar = st == :heatmap + if st == :contour + hascbar = (isscalar(series[:levels]) ? (series[:levels] > 1) : (length(series[:levels]) > 1)) && (length(unique(Array(series[:z]))) > 1) + end if series[:marker_z] != nothing || series[:line_z] != nothing || series[:fill_z] != nothing hascbar = true end From cd4b41a5379a6fd081d4acc9ff53bd5caaa7f8af Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 22:25:06 +0100 Subject: [PATCH 591/720] allow to pass a vector of colors for contour lines in PyPlot --- src/backends/pyplot.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index f5f60464..091a089e 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -646,13 +646,18 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) extrakw[:extend3d] = true end + if typeof(series[:linecolor]) <: AbstractArray + extrakw[:colors] = py_color.(series[:linecolor]) + else + extrakw[:cmap] = py_linecolormap(series) + end + # contour lines handle = ax[:contour](x, y, z, levelargs...; label = series[:label], zorder = series[:series_plotindex], linewidths = py_dpi_scale(plt, series[:linewidth]), linestyles = py_linestyle(st, series[:linestyle]), - cmap = py_linecolormap(series), extrakw... ) if series[:contour_labels] == true @@ -665,7 +670,6 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = ax[:contourf](x, y, z, levelargs...; label = series[:label], zorder = series[:series_plotindex] + 0.5, - cmap = py_fillcolormap(series), extrakw... ) push!(handles, handle) From d8f0612f5a124e4b111c8f9568d1d6062c6d415d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 22:51:06 +0100 Subject: [PATCH 592/720] implement contour_labels and partially vector of colors for Plotly(JS) --- src/backends/plotly.jl | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8f21f565..5dc7ccff 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -45,6 +45,7 @@ const _plotly_attr = merge_with_base_supported([ :framestyle, :tick_direction, :camera, + :contour_labels, ]) const _plotly_seriestype = [ @@ -434,6 +435,14 @@ function plotly_colorscale(grad::ColorGradient, α) [[grad.values[i], rgba_string(plot_color(grad.colors[i], α))] for i in 1:length(grad.colors)] end plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α) +function plotly_colorscale(c::AbstractVector{<:RGBA}, α) + if length(c) == 1 + return [[0.0, rgba_string(plot_color(c[1], α))]] + else + vals = linspace(0.0, 1.0, length(c)) + return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)] + end +end # plotly_colorscale(c, alpha = nothing) = plotly_colorscale(cgrad(), alpha) @@ -559,7 +568,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:x], d_out[:y], d_out[:z] = x, y, z # d_out[:showscale] = series[:colorbar] != :none d_out[:ncontours] = series[:levels] - d_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines") + d_out[:contours] = KW(:coloring => series[:fillrange] != nothing ? "fill" : "lines", :showlabels => series[:contour_labels] == true) d_out[:colorscale] = plotly_colorscale(series[:linecolor], series[:linealpha]) d_out[:showscale] = hascolorbar(sp) From 7cc60d0b0cdc3d1a7b6aaae3bfe3d01c97fef90a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 22:53:36 +0100 Subject: [PATCH 593/720] fix single-color case for plotly --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 5dc7ccff..3b72a836 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -437,7 +437,7 @@ end plotly_colorscale(c, α) = plotly_colorscale(cgrad(alpha=α), α) function plotly_colorscale(c::AbstractVector{<:RGBA}, α) if length(c) == 1 - return [[0.0, rgba_string(plot_color(c[1], α))]] + return [[0.0, rgba_string(plot_color(c[1], α))], [1.0, rgba_string(plot_color(c[1], α))]] else vals = linspace(0.0, 1.0, length(c)) return [[vals[i], rgba_string(plot_color(c[i], α))] for i in eachindex(c)] From c74adc652117087beb0151242cc69de796a94d85 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Feb 2018 23:00:46 +0100 Subject: [PATCH 594/720] check if a vector of the color black is passed to gr contour --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e320e8dd..7ff6f606 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1066,7 +1066,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) else GR.setlinetype(gr_linetype[series[:linestyle]]) GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) - if plot_color(series[:linecolor]) == plot_color(:black) + if plot_color(series[:linecolor]) == [plot_color(:black)] GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0)) else GR.contour(x, y, h, z, 1000 + (series[:contour_labels] == true ? 1 : 0)) From 461e93fc565c46349ee3528c09036dd84d3b87e0 Mon Sep 17 00:00:00 2001 From: Spencer Lyon Date: Wed, 28 Feb 2018 17:26:53 -0500 Subject: [PATCH 595/720] ENH: provide "application/vnd.plotly.v1+json" for Plotly and PlotlyJS backends For use in jupyterlab and nteract closes #1418 closes #1386 --- src/Plots.jl | 1 + src/backends/plotly.jl | 10 +++++----- src/output.jl | 30 +++++++++++++++++++++++++++--- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index 51d70256..222270cb 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -14,6 +14,7 @@ using Base.Meta @reexport using PlotThemes import Showoff import StatsBase +import JSON using Requires diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8f21f565..5c2c58e7 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -86,8 +86,6 @@ const _plotly_js_path_remote = "https://cdn.plot.ly/plotly-latest.min.js" function _initialize_backend(::PlotlyBackend; kw...) @eval begin - import JSON - _js_code = open(readstring, _plotly_js_path, "r") # borrowed from https://github.com/plotly/plotly.py/blob/2594076e29584ede2d09f2aa40a8a195b3f3fc66/plotly/offline/offline.py#L64-L71 c/o @spencerlyon2 @@ -740,15 +738,17 @@ function plotly_hover!(d_out::KW, hover) end # get a list of dictionaries, each representing the series params -function plotly_series_json(plt::Plot) +function plotly_series(plt::Plot) slist = [] for series in plt.series_list append!(slist, plotly_series(plt, series)) end - JSON.json(slist) - # JSON.json(map(series -> plotly_series(plt, series), plt.series_list)) + slist end +# get json string for a list of dictionaries, each representing the series params +plotly_series_json(plt::Plot) = JSON.json(plotly_series(plt)) + # ---------------------------------------------------------------- const _use_remote = Ref(false) diff --git a/src/output.jl b/src/output.jl index 99a55d50..3932d94b 100644 --- a/src/output.jl +++ b/src/output.jl @@ -261,23 +261,47 @@ end @require IJulia begin if IJulia.inited + """ + Add extra jupyter mimetypes to display_dict based on the plot backed. + + The default is nothing, except for plotly based backends, where it + adds data for `application/vnd.plotly.v1+json` that is used in + frontends like jupyterlab and nteract. + """ + _extra_mime_info!(plt::Plot, out::Dict) = out + function _extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict) + out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o) + out + end + + function _extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict) + out["application/vnd.plotly.v1+json"] = Dict( + :data => plotly_series(plt), + :layout => plotly_layout(plt) + ) + out + end + function IJulia.display_dict(plt::Plot) output_type = Symbol(plt.attr[:html_output_format]) if output_type == :auto output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) end + out = Dict() if output_type == :png mime = "image/png" - Dict{String,String}(mime => base64encode(show, MIME(mime), plt)) + out[mime] = base64encode(show, MIME(mime), plt) elseif output_type == :svg mime = "image/svg+xml" - Dict{String,String}(mime => sprint(show, MIME(mime), plt)) + out[mime] = sprint(show, MIME(mime), plt) elseif output_type == :html mime = "text/html" - Dict{String,String}(mime => sprint(show, MIME(mime), plt)) + out[mime] = sprint(show, MIME(mime), plt) else error("Unsupported output type $output_type") end + _extra_mime_info!(plt, out) + out end # default text/plain passes to html... handles Interact issues From 6b117234bc157c675bfe16b4b52df2a6ed944236 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 10 Feb 2018 22:16:23 +0000 Subject: [PATCH 596/720] Implement interactive linked axes for PyPlot. --- src/backends/pyplot.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 091a089e..24323e72 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1149,6 +1149,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # this sets the bg color inside the grid ax[set_facecolor_sym](py_color(sp[:background_color_inside])) + # link axes + x_ax_link, y_ax_link = sp[:xaxis].sps[1].o, sp[:yaxis].sps[1].o + ax != x_ax_link && ax[:get_shared_x_axes]()[:join](ax, sp[:xaxis].sps[1].o) + ax != y_ax_link && ax[:get_shared_y_axes]()[:join](ax, sp[:yaxis].sps[1].o) end py_drawfig(fig) end From da4111579dbefeb607734c75949aab954e665149 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sat, 10 Feb 2018 22:22:31 +0000 Subject: [PATCH 597/720] Implement interactive linked axes for Plotly. --- src/backends/plotly.jl | 58 +++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index a108e014..bfc934a7 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -232,7 +232,7 @@ function plotly_domain(sp::Subplot, letter) end -function plotly_axis(axis::Axis, sp::Subplot) +function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) letter = axis[:letter] framestyle = sp[:framestyle] ax = KW( @@ -252,7 +252,13 @@ function plotly_axis(axis::Axis, sp::Subplot) if letter in (:x,:y) ax[:domain] = plotly_domain(sp, letter) - ax[:anchor] = "$(letter==:x ? :y : :x)$(plotly_subplot_index(sp))" + if is3d(sp) + # don't link 3d axes for synchronized interactivity + x_idx = y_idx = sp[:subplot_index] + else + x_idx, y_idx = plotly_link_indicies(plt, sp) + end + ax[:anchor] = "$(letter==:x ? "y$(y_idx)" : "x$(x_idx)")" end ax[:tickangle] = -axis[:rotation] @@ -319,9 +325,8 @@ function plotly_layout(plt::Plot) d_out[:annotations] = KW[] for sp in plt.subplots - spidx = plotly_subplot_index(sp) - - + spidx = sp[:subplot_index] + x_idx, y_idx = plotly_link_indicies(plt, sp) # add an annotation for the title... positioned horizontally relative to plotarea, # but vertically just below the top of the subplot bounding box if sp[:title] != "" @@ -349,9 +354,9 @@ function plotly_layout(plt::Plot) azim = sp[:camera][1] - 90 #convert azimuthal to match GR behaviour theta = 90 - sp[:camera][2] #spherical coordinate angle from z axis d_out[:scene] = KW( - Symbol("xaxis$spidx") => plotly_axis(sp[:xaxis], sp), - Symbol("yaxis$spidx") => plotly_axis(sp[:yaxis], sp), - Symbol("zaxis$spidx") => plotly_axis(sp[:zaxis], sp), + Symbol("xaxis$(spidx)") => plotly_axis(plt, sp[:xaxis], sp), + Symbol("yaxis$(spidx)") => plotly_axis(plt, sp[:yaxis], sp), + Symbol("zaxis$(spidx)") => plotly_axis(plt, sp[:zaxis], sp), #2.6 multiplier set camera eye such that whole plot can be seen :camera => KW( @@ -363,11 +368,12 @@ function plotly_layout(plt::Plot) ), ) elseif ispolar(sp) - d_out[Symbol("angularaxis$spidx")] = plotly_polaraxis(sp[:xaxis]) - d_out[Symbol("radialaxis$spidx")] = plotly_polaraxis(sp[:yaxis]) + d_out[Symbol("angularaxis$(spidx)")] = plotly_polaraxis(sp[:xaxis]) + d_out[Symbol("radialaxis$(spidx)")] = plotly_polaraxis(sp[:yaxis]) else - d_out[Symbol("xaxis$spidx")] = plotly_axis(sp[:xaxis], sp) - d_out[Symbol("yaxis$spidx")] = plotly_axis(sp[:yaxis], sp) + d_out[Symbol("xaxis$(x_idx)")] = plotly_axis(plt, sp[:xaxis], sp) + # don't allow yaxis to be reupdated/reanchored in a linked subplot + spidx == y_idx ? d_out[Symbol("yaxis$(y_idx)")] = plotly_axis(plt, sp[:yaxis], sp) : nothing end # legend @@ -385,7 +391,7 @@ function plotly_layout(plt::Plot) # annotations for ann in sp[:annotations] - append!(d_out[:annotations], KW[plotly_annotation_dict(locate_annotation(sp, ann...)...; xref = "x$spidx", yref = "y$spidx")]) + append!(d_out[:annotations], KW[plotly_annotation_dict(locate_annotation(sp, ann...)...; xref = "x$(x_idx)", yref = "y$(y_idx)")]) end # series_annotations for series in series_list(sp) @@ -394,7 +400,7 @@ function plotly_layout(plt::Plot) push!(d_out[:annotations], plotly_annotation_dict( xi, yi, - PlotText(str,fnt); xref = "x$spidx", yref = "y$spidx") + PlotText(str,fnt); xref = "x$(x_idx)", yref = "y$(y_idx)") ) end end @@ -455,9 +461,15 @@ const _plotly_markers = KW( :hline => "line-ew", ) -function plotly_subplot_index(sp::Subplot) - spidx = sp[:subplot_index] - spidx == 1 ? "" : spidx +# find indicies of axes to which the supblot links to +function plotly_link_indicies(plt::Plot, sp::Subplot) + if plt[:link] in (:x, :y, :both) + x_idx = sp[:xaxis].sps[1][:subplot_index] + y_idx = sp[:yaxis].sps[1][:subplot_index] + else + x_idx = y_idx = sp[:subplot_index] + end + x_idx, y_idx end @@ -495,9 +507,9 @@ function plotly_series(plt::Plot, series::Series) d_out = KW() # these are the axes that the series should be mapped to - spidx = plotly_subplot_index(sp) - d_out[:xaxis] = "x$spidx" - d_out[:yaxis] = "y$spidx" + x_idx, y_idx = plotly_link_indicies(plt, sp) + d_out[:xaxis] = "x$(x_idx)" + d_out[:yaxis] = "y$(y_idx)" d_out[:showlegend] = should_add_to_legend(series) @@ -692,10 +704,10 @@ function plotly_series_shapes(plt::Plot, series::Series) # x, y = series[:x], series[:y] # these are the axes that the series should be mapped to - spidx = plotly_subplot_index(series[:subplot]) + x_idx, y_idx = plotly_link_indicies(plt, series[:subplot]) base_d = KW() - base_d[:xaxis] = "x$spidx" - base_d[:yaxis] = "y$spidx" + base_d[:xaxis] = "x$(x_idx)" + base_d[:yaxis] = "y$(y_idx)" base_d[:name] = series[:label] # base_d[:legendgroup] = series[:label] From 7c257a09f63c2b73e80eced4e77d15c3f40f688a Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Tue, 13 Mar 2018 09:18:32 -0600 Subject: [PATCH 598/720] Partially address #1409: group with named tuples (#1429) * group with named tuples * comma --- src/args.jl | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/args.jl b/src/args.jl index 0a06b64a..534210ad 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1012,15 +1012,28 @@ function extractGroupArgs(v::AVec, args...; legendEntry = string) GroupBy(map(legendEntry, groupLabels), groupIds) end -legendEntryFromTuple(ns::Tuple) = string(("$n " for n in ns)...) +legendEntryFromTuple(ns::Tuple) = join(ns, ' ') # this is when given a tuple of vectors of values to group by function extractGroupArgs(vs::Tuple, args...) - (vs == ()) && return GroupBy([""], [1:size(args[1],1)]) - v = collect(zip(vs...)) + isempty(vs) && return GroupBy([""], [1:size(args[1],1)]) + v = map(tuple, vs...) extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple) end +# allow passing NamedTuples for a named legend entry +@require NamedTuples begin + legendEntryFromTuple(ns::NamedTuples.NamedTuple) = + join(["$k = $v" for (k, v) in zip(keys(ns), values(ns))], ", ") + + function extractGroupArgs(vs::NamedTuples.NamedTuple, args...) + isempty(vs) && return GroupBy([""], [1:size(args[1],1)]) + NT = eval(:(NamedTuples.@NT($(keys(vs)...)))){map(eltype, vs)...} + v = map(NT, vs...) + extractGroupArgs(v, args...; legendEntry = legendEntryFromTuple) + end +end + # expecting a mapping of "group label" to "group indices" function extractGroupArgs(idxmap::Dict{T,V}, args...) where {T, V<:AVec{Int}} groupLabels = sortedkeys(idxmap) From bfa2fd2edcbc5994628e33b46cba630df05324c1 Mon Sep 17 00:00:00 2001 From: Yakir Luc Gagnon <12.yakir@gmail.com> Date: Wed, 14 Mar 2018 12:01:01 +0100 Subject: [PATCH 599/720] add option to supress saved message Added option `show_msg::Bool` to `buildanimation` to show/suppress the "Saved animation to..." message. --- src/animation.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/animation.jl b/src/animation.jl index 12fdb36b..6c1f880f 100644 --- a/src/animation.jl +++ b/src/animation.jl @@ -68,7 +68,8 @@ mp4(anim::Animation, fn = mp4fn(); kw...) = buildanimation(anim.dir, fn, false; function buildanimation(animdir::AbstractString, fn::AbstractString, is_animated_gif::Bool=true; fps::Integer = 20, loop::Integer = 0, - variable_palette::Bool=false) + variable_palette::Bool=false, + show_msg::Bool=true) fn = abspath(fn) if is_animated_gif @@ -86,7 +87,7 @@ function buildanimation(animdir::AbstractString, fn::AbstractString, run(`ffmpeg -v 0 -framerate $fps -loop $loop -i $(animdir)/%06d.png -pix_fmt yuv420p -y $fn`) end - info("Saved animation to ", fn) + show_msg && info("Saved animation to ", fn) AnimatedGif(fn) end From d183d579cfc51020a7f54008209663f07846fe1a Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Thu, 15 Mar 2018 19:13:38 +0100 Subject: [PATCH 600/720] Link axes before adding series. --- src/plot.jl | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plot.jl b/src/plot.jl index 5f8f69d9..2b7ab389 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -102,8 +102,13 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...) end end - # create the layout and initialize the subplots + # create the layout plt.layout, plt.subplots, plt.spmap = build_layout(layout, num_sp, copy(plts)) + + # do we need to link any axes together? + link_axes!(plt.layout, plt[:link]) + + # initialize the subplots cmdidx = 1 for (idx, sp) in enumerate(plt.subplots) _initialize_subplot(plt, sp) @@ -127,9 +132,6 @@ function plot(plt1::Plot, plts_tail::Plot...; kw...) _update_subplot_args(plt, sp, d, idx, false) end - # do we need to link any axes together? - link_axes!(plt.layout, plt[:link]) - # finish up current(plt) _do_plot_show(plt, get(d, :show, default(:show))) From 7f6fe09a002be68355546b741576788562c0df44 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 15 Mar 2018 21:22:29 +0100 Subject: [PATCH 601/720] fix magic fill argument --- src/args.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/args.jl b/src/args.jl index 534210ad..68354760 100644 --- a/src/args.jl +++ b/src/args.jl @@ -751,6 +751,10 @@ function processFillArg(d::KW, arg) elseif allAlphas(arg) d[:fillalpha] = arg + # fillrange provided as vector or number + elseif typeof(arg) <: Union{AbstractArray{<:Real}, Real} + d[:fillrange] = arg + elseif !handleColors!(d, arg, :fillcolor) d[:fillrange] = arg From 501df8cfb97435992d1969233fb7dd4e89e1fffc Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 15 Mar 2018 21:46:19 +0100 Subject: [PATCH 602/720] allow passing Real or 2Tuple of Reals as fillrange for Plotly --- src/backends/plotly.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index a108e014..1071f802 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -536,7 +536,7 @@ function plotly_series(plt::Plot, series::Series) if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple) d_out[:fill] = "tozeroy" d_out[:fillcolor] = rgba_string(series[:fillcolor]) - elseif isa(series[:fillrange], AbstractVector) + elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real} d_out[:fill] = "tonexty" d_out[:fillcolor] = rgba_string(series[:fillcolor]) elseif !(series[:fillrange] in (false, nothing)) @@ -665,6 +665,14 @@ function plotly_series(plt::Plot, series::Series) # series, one for series being filled to) instead of one d_out_fillrange = deepcopy(d_out) d_out_fillrange[:showlegend] = false + # if fillrange is provided as real or tuple of real, expand to array + if typeof(series[:fillrange]) <: Real + series[:fillrange] = fill(series[:fillrange], length(series[:x])) + elseif typeof(series[:fillrange]) <: Tuple + f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(series[:x])) : series[:fillrange][1] + f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(series[:x])) : series[:fillrange][2] + series[:fillrange] = (f1, f2) + end if isa(series[:fillrange], AbstractVector) d_out_fillrange[:y] = series[:fillrange] delete!(d_out_fillrange, :fill) From 7d58090e598d531c7daa3ed56ac6a0e0cd0de081 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 16 Mar 2018 09:36:24 +0100 Subject: [PATCH 603/720] use bar recipe in plotly --- src/backends/plotly.jl | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index a108e014..718f7add 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -49,7 +49,7 @@ const _plotly_attr = merge_with_base_supported([ ]) const _plotly_seriestype = [ - :path, :scatter, :bar, :pie, :heatmap, + :path, :scatter, :pie, :heatmap, :contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl, ] const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot] @@ -544,17 +544,6 @@ function plotly_series(plt::Plot, series::Series) end d_out[:x], d_out[:y] = x, y - elseif st == :bar - d_out[:type] = "bar" - d_out[:x], d_out[:y], d_out[:orientation] = if isvertical(series) - x, y, "v" - else - y, x, "h" - end - d_out[:width] = series[:bar_width] - d_out[:marker] = KW(:color => _cycle(rgba_string.(series[:fillcolor]),eachindex(series[:x])), - :line => KW(:width => series[:linewidth])) - elseif st == :heatmap d_out[:type] = "heatmap" d_out[:x], d_out[:y], d_out[:z] = x, y, z From 717aed5a06465670e1d41d89eb6887c788837163 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 16 Mar 2018 11:26:56 +0100 Subject: [PATCH 604/720] allow ticks = :all and ticks = n::Int for categorical axes --- src/axes.jl | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 855f8d97..75df88e7 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -238,10 +238,18 @@ function get_ticks(axis::Axis) ticks = ticks == :native ? :auto : ticks dvals = axis[:discrete_values] - cv, dv = if !isempty(dvals) && ticks == :auto + cv, dv = if !isempty(dvals) # discrete ticks... - axis[:continuous_values], dvals - elseif ticks == :auto + n = length(dvals) + rng = if ticks == :auto + Int[round(Int,i) for i in linspace(1, n, 15)] + elseif ticks == :all + 1:n + elseif typeof(ticks) <: Int + Int[round(Int,i) for i in linspace(1, n, ticks)] + end + axis[:continuous_values][rng], dvals[rng] + elseif typeof(ticks) <: Symbol if ispolar(axis.sps[1]) && axis[:letter] == :x #force theta axis to be full circle (collect(0:pi/4:7pi/4), string.(0:45:315)) @@ -260,13 +268,7 @@ function get_ticks(axis::Axis) end # @show ticks dvals cv dv - # TODO: better/smarter cutoff values for sampling ticks - if length(cv) > 30 && ticks == :auto - rng = Int[round(Int,i) for i in linspace(1, length(cv), 15)] - cv[rng], dv[rng] - else - cv, dv - end + return cv, dv end _transform_ticks(ticks) = ticks From c273bf6a7bb7afea9e7167077dda712348e2aaa3 Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Sun, 18 Mar 2018 17:25:45 +0000 Subject: [PATCH 605/720] Partial attempt to fix label scaling to atomatically scientific notation. Note, that the logic of replacing scientific notation in GR backend is a bit dodgy. --- src/axes.jl | 2 +- src/backends/gr.jl | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 855f8d97..1cecd211 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -212,7 +212,7 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) formatter = axis[:formatter] if formatter == :auto # the default behavior is to make strings of the scaled values and then apply the labelfunc - map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain)) + map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :auto)) elseif formatter == :scientific Showoff.showoff(unscaled_ticks, :scientific) else diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 7ff6f606..f259f143 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -223,7 +223,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) - if yaxis[:formatter] == :scientific && yaxis[:ticks] in (:auto, :native) + if (yaxis[:formatter] == :scientific || contains(rtick_labels,"×10") )&& yaxis[:ticks] in (:auto, :native) rtick_labels = convert_sci_unicode(rtick_labels) end @@ -889,7 +889,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # ensure correct dispatch in gr_text for automatic log ticks if xaxis[:scale] in _logScales dv = string(dv, "\\ ") - elseif xaxis[:formatter] == :scientific + elseif xaxis[:formatter] == :scientific || contains(dv,"×10") dv = convert_sci_unicode(dv) end end @@ -908,7 +908,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # ensure correct dispatch in gr_text for automatic log ticks if yaxis[:scale] in _logScales dv = string(dv, "\\ ") - elseif yaxis[:formatter] == :scientific + elseif yaxis[:formatter] == :scientific || contains(dv,"×10") dv = convert_sci_unicode(dv) end end From bffd9bcb53701a08cb251e127e811011c8be3d42 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 18 Mar 2018 23:15:45 +0100 Subject: [PATCH 606/720] :straightline seriestype and gr implementation --- src/axes.jl | 11 +++++++---- src/backends/gr.jl | 12 ++++++++---- src/recipes.jl | 24 +++++++----------------- src/utils.jl | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 855f8d97..43813b89 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -287,8 +287,8 @@ end function expand_extrema!(ex::Extrema, v::Number) - ex.emin = NaNMath.min(v, ex.emin) - ex.emax = NaNMath.max(v, ex.emax) + ex.emin = isfinite(v) ? min(v, ex.emin) : ex.emin + ex.emax = isfinite(v) ? max(v, ex.emax) : ex.emax ex end @@ -303,8 +303,8 @@ expand_extrema!(axis::Axis, ::Bool) = axis[:extrema] function expand_extrema!(axis::Axis, v::Tuple{MIN,MAX}) where {MIN<:Number,MAX<:Number} ex = axis[:extrema] - ex.emin = NaNMath.min(v[1], ex.emin) - ex.emax = NaNMath.max(v[2], ex.emax) + ex.emin = isfinite(v[1]) ? min(v[1], ex.emin) : ex.emin + ex.emax = isfinite(v[2]) ? max(v[2], ex.emax) : ex.emax ex end function expand_extrema!(axis::Axis, v::AVec{N}) where N<:Number @@ -326,6 +326,9 @@ function expand_extrema!(sp::Subplot, d::KW) else letter == :x ? :y : letter == :y ? :x : :z end] + if letter != :z && d[:seriestype] == :straightline && any(series[:seriestype] != :straightline for series in series_list(sp)) && data[1] != data[2] + data = [NaN] + end axis = sp[Symbol(letter, "axis")] if isa(data, Volume) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 7ff6f606..6cc3ef19 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -48,7 +48,7 @@ const _gr_attr = merge_with_base_supported([ :contour_labels, ]) const _gr_seriestype = [ - :path, :scatter, + :path, :scatter, :straightline, :heatmap, :pie, :image, :contour, :path3d, :scatter3d, :surface, :wireframe, :shape @@ -1014,7 +1014,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) x, y = convert_to_polar(x, y, (rmin, rmax)) end - if st in (:path, :scatter) + if st == :straightline + x, y = straightline_data(sp, series) + end + + if st in (:path, :scatter, :straightline) if length(x) > 1 lz = series[:line_z] segments_iterator = if lz != nothing && length(lz) > 1 @@ -1036,7 +1040,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end # draw the line(s) - if st == :path + if st in (:path, :straightline) for (i, rng) in enumerate(segments_iterator) gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none @@ -1295,7 +1299,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) st == :shape && gr_polyline(x, y) end - if st == :path + if st in (:path, :straightline) GR.settransparency(gr_alpha(series[:linealpha])) if series[:fillrange] == nothing || series[:ribbon] != nothing GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) diff --git a/src/recipes.jl b/src/recipes.jl index aa37ee5c..bfe7d0b4 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -79,28 +79,26 @@ function hvline_limits(axis::Axis) end @recipe function f(::Type{Val{:hline}}, x, y, z) - xmin, xmax = hvline_limits(plotattributes[:subplot][:xaxis]) n = length(y) - newx = repmat(Float64[xmin, xmax, NaN], n) + newx = repmat(Float64[-1, 1, NaN], n) newy = vec(Float64[yi for i=1:3,yi=y]) x := newx y := newy - seriestype := :path + seriestype := :straightline () end -@deps hline path +@deps hline straightline @recipe function f(::Type{Val{:vline}}, x, y, z) - ymin, ymax = hvline_limits(plotattributes[:subplot][:yaxis]) n = length(y) newx = vec(Float64[yi for i=1:3,yi=y]) - newy = repmat(Float64[ymin, ymax, NaN], n) + newy = repmat(Float64[-1, 1, NaN], n) x := newx y := newy - seriestype := :path + seriestype := :straightline () end -@deps vline path +@deps vline straightline # --------------------------------------------------------------------------- # path and scatter @@ -999,15 +997,7 @@ end # ------------------------------------------------- "Adds a+bx... straight line over the current plot, without changing the axis limits" -function abline!(plt::Plot, a, b; kw...) - xl, yl = xlims(plt), ylims(plt) - x1, x2 = max(xl[1], (yl[1] - b)/a), min(xl[2], (yl[2] - b)/a) - if x2 > x1 - plot!(plt, x -> b + a*x, x1, x2; kw...) - else - nothing - end -end +abline!(plt::Plot, a, b; kw...) = plot!(plt, [0, 1], [b, b+a]; seriestype = :straightline, kw...) abline!(args...; kw...) = abline!(current(), args...; kw...) diff --git a/src/utils.jl b/src/utils.jl index cdab41c6..8710a5af 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1079,3 +1079,44 @@ function convert_sci_unicode(label::AbstractString) end label end + +function straightline_data(sp::Subplot, series::Series) + xl, yl = isvertical(series.d) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp)) + x, y = series[:x], series[:y] + n = length(x) + if n == 2 + return straightline_data(xl, yl, x, y) + else + k, r = divrem(n, 3) + if r == 0 + xdata, ydata = fill(NaN, n), fill(NaN, n) + for i in 1:k + inds = (3 * i - 2):(3 * i - 1) + xdata[inds], ydata[inds] = straightline_data(xl, yl, x[inds], y[inds]) + end + return xdata, ydata + else + error("Misformed data. `straightline_data` either accepts vectors of length 2 or 3k. The provided series has length $n") + end + end +end + +function straightline_data(xl, yl, x, y) + if y[1] == y[2] + if x[1] == x[2] + error("Two identical points cannot be used to describe a straight line.") + else + return [xl[1], xl[2]], [y[1], y[2]] + end + elseif x[1] == x[2] + return [x[1], x[2]], [yl[1], yl[2]] + else + # get a and b from the line y = a * x + b through the points given by + # the coordinates x and x + b = y[1] - (y[1] - y[2]) * x[1] / (x[1] - x[2]) + a = (y[1] - y[2]) / (x[1] - x[2]) + # get the data values + xdata = [clamp(x[1] + (x[1] - x[2]) * (ylim - y[1]) / (y[1] - y[2]), xl...) for ylim in yl] + return xdata, a .* xdata .+ b + end +end From 6b6394ba9779b1351f8bb3cb5d067071877a8dea Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Mon, 19 Mar 2018 03:15:14 +0000 Subject: [PATCH 607/720] Fixed bug introduced into GR Polar plot --- src/backends/gr.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index f259f143..692f33c8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -223,7 +223,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) - if (yaxis[:formatter] == :scientific || contains(rtick_labels,"×10") )&& yaxis[:ticks] in (:auto, :native) + if (yaxis[:formatter] == :scientific || any(contains.(rtick_labels,"×10"))) && yaxis[:ticks] in (:auto, :native) rtick_labels = convert_sci_unicode(rtick_labels) end From bbff66a0417c84d2c413ecbe6bc8055c3fd395a3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Mar 2018 14:55:38 +0100 Subject: [PATCH 608/720] glvisualize() :straightline --- src/backends/glvisualize.jl | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index b0841596..dd4cfb51 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -51,7 +51,7 @@ const _glvisualize_attr = merge_with_base_supported([ :tick_direction, ]) const _glvisualize_seriestype = [ - :path, :shape, + :path, :shape, :straightline, :scatter, :hexbin, :bar, :boxplot, :heatmap, :image, :volume, @@ -290,6 +290,10 @@ function extract_points(d) array = (d[:x], d[:y], d[:z])[1:dim] topoints(Point{dim, Float32}, array) end +function extract_straightline_points(sp::Subplot, series::Series) + x, y = straightline_data(sp, series) + topoints(Point{2, Float32}, (x, y)) +end function make_gradient(grad::Vector{C}) where C <: Colorant grad end @@ -1102,9 +1106,9 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) kw_args[:stroke_width] = Float32(d[:linewidth]/100f0) end vis = GL.gl_surface(x, y, z, kw_args) - elseif (st in (:path, :path3d)) && d[:linewidth] > 0 + elseif (st in (:path, :path3d, :straightline)) && d[:linewidth] > 0 kw = copy(kw_args) - points = Plots.extract_points(d) + points = st == :straightline ? extract_straightline_points(sp, series) : Plots.extract_points(d) extract_linestyle(d, kw) vis = GL.gl_lines(points, kw) if d[:markershape] != :none @@ -1460,7 +1464,7 @@ function make_label(sp, series, i) d = series.d st = d[:seriestype] kw_args = KW() - if (st in (:path, :path3d)) && d[:linewidth] > 0 + if (st in (:path, :path3d, :straightline)) && d[:linewidth] > 0 points = Point2f0[(0, ho), (w, ho)] kw = KW() extract_linestyle(d, kw) From c8cdade88409645b7c0d9b5e7f057c41c564d37b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Mar 2018 16:24:23 +0100 Subject: [PATCH 609/720] :straightline for all backends --- src/backends/glvisualize.jl | 12 ++++++------ src/backends/gr.jl | 2 +- src/backends/hdf5.jl | 4 ++-- src/backends/inspectdr.jl | 10 +++++++--- src/backends/pgfplots.jl | 4 +++- src/backends/plotly.jl | 11 ++++++++--- src/backends/pyplot.jl | 9 ++++++--- src/backends/unicodeplots.jl | 12 ++++++++---- src/utils.jl | 5 +++-- 9 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index dd4cfb51..ba8a46f9 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -287,13 +287,13 @@ function topoints(::Type{P}, array) where P end function extract_points(d) dim = is3d(d) ? 3 : 2 - array = (d[:x], d[:y], d[:z])[1:dim] + array = if d[:seriestype] == :straightline + straightline_data(d) + else + (d[:x], d[:y], d[:z])[1:dim] + end topoints(Point{dim, Float32}, array) end -function extract_straightline_points(sp::Subplot, series::Series) - x, y = straightline_data(sp, series) - topoints(Point{2, Float32}, (x, y)) -end function make_gradient(grad::Vector{C}) where C <: Colorant grad end @@ -1108,7 +1108,7 @@ function _display(plt::Plot{GLVisualizeBackend}, visible = true) vis = GL.gl_surface(x, y, z, kw_args) elseif (st in (:path, :path3d, :straightline)) && d[:linewidth] > 0 kw = copy(kw_args) - points = st == :straightline ? extract_straightline_points(sp, series) : Plots.extract_points(d) + points = Plots.extract_points(d) extract_linestyle(d, kw) vis = GL.gl_lines(points, kw) if d[:markershape] != :none diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 6cc3ef19..bca3362b 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1015,7 +1015,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if st == :straightline - x, y = straightline_data(sp, series) + x, y = straightline_data(series) end if st in (:path, :scatter, :straightline) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index 3e5afa87..2e677625 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -29,7 +29,7 @@ Read from .hdf5 file using: ==# @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "hdf5.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "hdf5.jl")) end import FixedPointNumbers: N0f8 #In core Julia @@ -97,7 +97,7 @@ const _hdf5_attr = merge_with_base_supported([ :colorbar_title, ]) const _hdf5_seriestype = [ - :path, :steppre, :steppost, :shape, + :path, :steppre, :steppost, :shape, :straightline, :scatter, :hexbin, #:histogram2d, :histogram, # :bar, :heatmap, :pie, :image, diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 3718b2ee..3558040f 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -57,7 +57,7 @@ const _inspectdr_attr = merge_with_base_supported([ ]) const _inspectdr_style = [:auto, :solid, :dash, :dot, :dashdot] const _inspectdr_seriestype = [ - :path, :scatter, :shape #, :steppre, :steppost + :path, :scatter, :shape, :straightline, #, :steppre, :steppost ] #see: _allMarkers, _shape_keys const _inspectdr_marker = Symbol[ @@ -243,7 +243,11 @@ function _series_added(plt::Plot{InspectDRBackend}, series::Series) 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]) + x, y = if st == :straightline + straightline_data(series) + else + _vectorize(series[:x]), _vectorize(series[:y]) + end #No support for polar grid... but can still perform polar transformation: if ispolar(sp) @@ -299,7 +303,7 @@ For st in :shape: color = linecolor, fillcolor = fillcolor ) end - elseif st in (:path, :scatter) #, :steppre, :steppost) + elseif st in (:path, :scatter, :straightline) #, :steppre, :steppost) #NOTE: In Plots.jl, :scatter plots have 0-linewidths (I think). linewidth = series[:linewidth] #More efficient & allows some support for markerstrokewidth: diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index ef2920ad..027a88a9 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -39,7 +39,7 @@ const _pgfplots_attr = merge_with_base_supported([ :framestyle, :camera, ]) -const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape] +const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape, :straightline,] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] const _pgfplots_marker = [:none, :auto, :circle, :rect, :diamond, :utriangle, :dtriangle, :cross, :xcross, :star5, :pentagon, :hline] #vcat(_allMarkers, Shape) const _pgfplots_scale = [:identity, :ln, :log2, :log10] @@ -220,6 +220,8 @@ function pgf_series(sp::Subplot, series::Series) d[:z].surf, d[:x], d[:y] elseif is3d(st) d[:x], d[:y], d[:z] + elseif st == :straightline + straightline_data(series) elseif d[:marker_z] != nothing # If a marker_z is used pass it as third coordinate to a 2D plot. # See "Scatter Plots" in PGFPlots documentation diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index a108e014..e2207f0d 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -51,6 +51,7 @@ const _plotly_attr = merge_with_base_supported([ const _plotly_seriestype = [ :path, :scatter, :bar, :pie, :heatmap, :contour, :surface, :wireframe, :path3d, :scatter3d, :shape, :scattergl, + :straightline ] const _plotly_style = [:auto, :solid, :dash, :dot, :dashdot] const _plotly_marker = [ @@ -510,12 +511,16 @@ function plotly_series(plt::Plot, series::Series) plotly_data(series[letter]) end), (:x, :y, :z)) + if st == :straightline + x, y = straightline_data(series) + end + d_out[:name] = series[:label] isscatter = st in (:scatter, :scatter3d, :scattergl) hasmarker = isscatter || series[:markershape] != :none - hasline = st in (:path, :path3d) - hasfillrange = st in (:path, :scatter, :scattergl) && + hasline = st in (:path, :path3d, :straightline) + hasfillrange = st in (:path, :scatter, :scattergl, :straightline) && (isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple)) d_out[:colorbar] = KW(:title => sp[:colorbar_title]) @@ -526,7 +531,7 @@ function plotly_series(plt::Plot, series::Series) end # set the "type" - if st in (:path, :scatter, :scattergl) + if st in (:path, :scatter, :scattergl, :straightline) d_out[:type] = st==:scattergl ? "scattergl" : "scatter" d_out[:mode] = if hasmarker hasline ? "lines+markers" : "markers" diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 091a089e..5d4d8e16 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -45,7 +45,7 @@ const _pyplot_attr = merge_with_base_supported([ :contour_labels, ]) const _pyplot_seriestype = [ - :path, :steppre, :steppost, :shape, + :path, :steppre, :steppost, :shape, :straightline, :scatter, :hexbin, #:histogram2d, :histogram, # :bar, :heatmap, :pie, :image, @@ -452,6 +452,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # ax = getAxis(plt, series) x, y, z = series[:x], series[:y], series[:z] + if st == :straightline + x, y = straightline_data(series) + end xyargs = (st in _3dTypes ? (x,y,z) : (x,y)) # handle zcolor and get c/cmap @@ -485,7 +488,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # for each plotting command, optionally build and add a series handle to the list # line plot - if st in (:path, :path3d, :steppre, :steppost) + if st in (:path, :path3d, :steppre, :steppost, :straightline) if series[:linewidth] > 0 if series[:line_z] == nothing handle = ax[:plot](xyargs...; @@ -1244,7 +1247,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) facecolor = py_color(_cycle(series[:fillcolor],1)), linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), ) - elseif series[:seriestype] == :path + elseif series[:seriestype] in (:path, :straightline) PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(_cycle(series[:linecolor],1)), linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 99482750..f53435d2 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -2,7 +2,7 @@ # https://github.com/Evizero/UnicodePlots.jl @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "unicodeplots.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "unicodeplots.jl")) end const _unicodeplots_attr = merge_with_base_supported([ @@ -17,7 +17,7 @@ const _unicodeplots_attr = merge_with_base_supported([ :guide, :lims, ]) const _unicodeplots_seriestype = [ - :path, :scatter, + :path, :scatter, :straightline, # :bar, :shape, :histogram2d, @@ -142,7 +142,7 @@ function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) return end - if st == :path + if st in (:path, :straightline) func = UnicodePlots.lineplot! elseif st == :scatter || d[:markershape] != :none func = UnicodePlots.scatterplot! @@ -155,7 +155,11 @@ function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) end # get the series data and label - x, y = [collect(float(d[s])) for s in (:x, :y)] + x, y = if st == :straightline + straightline_data(d) + else + [collect(float(d[s])) for s in (:x, :y)] + end label = addlegend ? d[:label] : "" # if we happen to pass in allowed color symbols, great... otherwise let UnicodePlots decide diff --git a/src/utils.jl b/src/utils.jl index 8710a5af..d68ca24d 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1080,8 +1080,9 @@ function convert_sci_unicode(label::AbstractString) label end -function straightline_data(sp::Subplot, series::Series) - xl, yl = isvertical(series.d) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp)) +function straightline_data(series) + sp = series[:subplot] + xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp)) x, y = series[:x], series[:y] n = length(x) if n == 2 From 9a5f42c251e48f356ad38335725341b2679a3e6f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Mar 2018 21:34:55 +0100 Subject: [PATCH 610/720] infinite shapes --- src/backends/glvisualize.jl | 2 ++ src/backends/gr.jl | 1 + src/backends/inspectdr.jl | 1 + src/backends/pgfplots.jl | 2 ++ src/backends/plotly.jl | 2 +- src/backends/pyplot.jl | 2 ++ src/backends/unicodeplots.jl | 2 ++ src/utils.jl | 22 ++++++++++++++++++++++ 8 files changed, 33 insertions(+), 1 deletion(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index ba8a46f9..f895df8b 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -289,6 +289,8 @@ function extract_points(d) dim = is3d(d) ? 3 : 2 array = if d[:seriestype] == :straightline straightline_data(d) + elseif d[:seriestype] == :shape + shape_data(series) else (d[:x], d[:y], d[:z])[1:dim] end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index bca3362b..2ab89c5d 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1186,6 +1186,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.selntran(1) elseif st == :shape + x, y = shape_data(series) for (i,rng) in enumerate(iter_segments(x, y)) if length(rng) > 1 # connect to the beginning diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index 3558040f..d0d3e285 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -272,6 +272,7 @@ For st in :shape: =# if st in (:shape,) + x, y = shape_data(series) nmax = 0 for (i,rng) in enumerate(iter_segments(x, y)) nmax = i diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 027a88a9..bda7ac16 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -222,6 +222,8 @@ function pgf_series(sp::Subplot, series::Series) d[:x], d[:y], d[:z] elseif st == :straightline straightline_data(series) + elseif st == :shape + shape_data(series) elseif d[:marker_z] != nothing # If a marker_z is used pass it as third coordinate to a 2D plot. # See "Scatter Plots" in PGFPlots documentation diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index e2207f0d..78820871 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -704,7 +704,7 @@ function plotly_series_shapes(plt::Plot, series::Series) base_d[:name] = series[:label] # base_d[:legendgroup] = series[:label] - x, y = plotly_data(series[:x]), plotly_data(series[:y]) + x, y = shape_data(series) for (i,rng) in enumerate(iter_segments(x,y)) length(rng) < 2 && continue diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 5d4d8e16..30d6a95a 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -454,6 +454,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) x, y, z = series[:x], series[:y], series[:z] if st == :straightline x, y = straightline_data(series) + elseif st == :shape + x, y = shape_data(series) end xyargs = (st in _3dTypes ? (x,y,z) : (x,y)) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index f53435d2..8b26f6e7 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -157,6 +157,8 @@ function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) # get the series data and label x, y = if st == :straightline straightline_data(d) + elseif st == :shape + shape_data(series) else [collect(float(d[s])) for s in (:x, :y)] end diff --git a/src/utils.jl b/src/utils.jl index d68ca24d..933ea2c6 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1121,3 +1121,25 @@ function straightline_data(xl, yl, x, y) return xdata, a .* xdata .+ b end end + +function shape_data(series) + sp = series[:subplot] + xl, yl = isvertical(series) ? (xlims(sp), ylims(sp)) : (ylims(sp), xlims(sp)) + x, y = series[:x], series[:y] + factor = 100 + for i in eachindex(x) + if x[i] == -Inf + x[i] = xl[1] - factor * (xl[2] - xl[1]) + elseif x[i] == Inf + x[i] = xl[2] + factor * (xl[2] - xl[1]) + end + end + for i in eachindex(y) + if y[i] == -Inf + y[i] = yl[1] - factor * (yl[2] - yl[1]) + elseif y[i] == Inf + y[i] = yl[2] + factor * (yl[2] - yl[1]) + end + end + return x, y +end From 1c0a731ff6e1d5e913d1aa7da7d5ae0bd3a7cd2b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 19 Mar 2018 21:51:02 +0100 Subject: [PATCH 611/720] fix typo in glvisualize --- src/backends/glvisualize.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/glvisualize.jl b/src/backends/glvisualize.jl index f895df8b..b8a4ed04 100644 --- a/src/backends/glvisualize.jl +++ b/src/backends/glvisualize.jl @@ -290,7 +290,7 @@ function extract_points(d) array = if d[:seriestype] == :straightline straightline_data(d) elseif d[:seriestype] == :shape - shape_data(series) + shape_data(d) else (d[:x], d[:y], d[:z])[1:dim] end From 4e5c88eb74a11e9c7a77a1bf663d81de44603f28 Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Wed, 21 Mar 2018 00:12:57 +0000 Subject: [PATCH 612/720] Fixed unicode display for plotly() --- src/backends/web.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/web.jl b/src/backends/web.jl index 36fd5d06..e38ad782 100644 --- a/src/backends/web.jl +++ b/src/backends/web.jl @@ -12,6 +12,7 @@ function standalone_html(plt::AbstractPlot; title::AbstractString = get(plt.attr $title + $(html_head(plt)) From bd06f0c71306192caa5d26c5987c225686884a06 Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Wed, 21 Mar 2018 09:54:52 +0000 Subject: [PATCH 613/720] Fixed broken behaviour for function :formatter, and pgfplots --- src/backends/gr.jl | 8 ++++---- src/backends/pgfplots.jl | 3 ++- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 692f33c8..88fcad36 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -223,8 +223,8 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) sinf = sind.(a) cosf = cosd.(a) rtick_values, rtick_labels = get_ticks(yaxis) - if (yaxis[:formatter] == :scientific || any(contains.(rtick_labels,"×10"))) && yaxis[:ticks] in (:auto, :native) - rtick_labels = convert_sci_unicode(rtick_labels) + if yaxis[:formatter] in (:scientific, :auto) && yaxis[:ticks] in (:auto, :native) + rtick_labels = convert_sci_unicode.(rtick_labels) end #draw angular grid @@ -889,7 +889,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # ensure correct dispatch in gr_text for automatic log ticks if xaxis[:scale] in _logScales dv = string(dv, "\\ ") - elseif xaxis[:formatter] == :scientific || contains(dv,"×10") + elseif xaxis[:formatter] in (:scientific, :auto) dv = convert_sci_unicode(dv) end end @@ -908,7 +908,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # ensure correct dispatch in gr_text for automatic log ticks if yaxis[:scale] in _logScales dv = string(dv, "\\ ") - elseif yaxis[:formatter] == :scientific || contains(dv,"×10") + elseif yaxis[:formatter] in (:scientific, :auto) dv = convert_sci_unicode(dv) end end diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index ef2920ad..0f28ac57 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -329,7 +329,8 @@ function pgf_axis(sp::Subplot, letter) push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}")) elseif axis[:showaxis] tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2] - tick_labels = axis[:formatter] == :scientific ? string.("\$", convert_sci_unicode.(tick_labels), "\$") : tick_labels + tick_labels = ( axis[:formatter] in (:scientific, :auto) ? + string.("\$", convert_sci_unicode.(tick_labels), "\$") : tick_labels ) push!(style, string(letter, "ticklabels = {", join(tick_labels,","), "}")) else push!(style, string(letter, "ticklabels = {}")) From 0ace28b784d8f254cd1521f6f7d5910c46428914 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 21 Mar 2018 11:42:01 +0100 Subject: [PATCH 614/720] extend straightline data beyond axes limits --- src/utils.jl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 933ea2c6..e8ded4ec 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1103,14 +1103,14 @@ function straightline_data(series) end function straightline_data(xl, yl, x, y) - if y[1] == y[2] + x_vals, y_vals = if y[1] == y[2] if x[1] == x[2] error("Two identical points cannot be used to describe a straight line.") else - return [xl[1], xl[2]], [y[1], y[2]] + [xl[1], xl[2]], [y[1], y[2]] end elseif x[1] == x[2] - return [x[1], x[2]], [yl[1], yl[2]] + [x[1], x[2]], [yl[1], yl[2]] else # get a and b from the line y = a * x + b through the points given by # the coordinates x and x @@ -1118,8 +1118,15 @@ function straightline_data(xl, yl, x, y) a = (y[1] - y[2]) / (x[1] - x[2]) # get the data values xdata = [clamp(x[1] + (x[1] - x[2]) * (ylim - y[1]) / (y[1] - y[2]), xl...) for ylim in yl] - return xdata, a .* xdata .+ b + + xdata, a .* xdata .+ b end + # expand the data outside the axis limits, by a certain factor too improve + # plotly(js) and interactive behaviour + factor = 100 + x_vals = x_vals .+ (x_vals[2] - x_vals[1]) .* factor .* [-1, 1] + y_vals = y_vals .+ (y_vals[2] - y_vals[1]) .* factor .* [-1, 1] + return x_vals, y_vals end function shape_data(series) From 92f9ccce5c58c5412a2cbebb9ec30b75260fa4fb Mon Sep 17 00:00:00 2001 From: Fedor Bezrukov Date: Wed, 21 Mar 2018 23:58:26 +0000 Subject: [PATCH 615/720] Added :plain formatter --- src/axes.jl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/axes.jl b/src/axes.jl index 1cecd211..089840ac 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -213,11 +213,19 @@ function optimal_ticks_and_labels(axis::Axis, ticks = nothing) if formatter == :auto # the default behavior is to make strings of the scaled values and then apply the labelfunc map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :auto)) + elseif formatter == :plain + # Leave the numbers in plain format + map(labelfunc(scale, backend()), Showoff.showoff(scaled_ticks, :plain)) elseif formatter == :scientific Showoff.showoff(unscaled_ticks, :scientific) else # there was an override for the formatter... use that on the unscaled ticks map(formatter, unscaled_ticks) + # if the formatter left us with numbers, still apply the default formatter + # However it leave us with the problem of unicode number decoding by the backend + # if eltype(unscaled_ticks) <: Number + # Showoff.showoff(unscaled_ticks, :auto) + # end end else # no finite ticks to show... From b2f92e246eb729f99bac89710961f1175e692ea1 Mon Sep 17 00:00:00 2001 From: piever Date: Thu, 22 Mar 2018 19:39:18 +0000 Subject: [PATCH 616/720] update news --- NEWS.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b4b51cdd..265d53fd 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,7 +3,7 @@ #### notes on release changes, ongoing development, and future planned work -- All new development should target 0.14! +- All new development should target 0.15! - Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - `backports` branch is for Julia 0.5 @@ -11,6 +11,23 @@ --- ## (current master) +## 0.15.1 + +- fix scientific notation for labels in GR +- fix labels with logscale +- fix image cropping with GR +- fix grouping of annotations +- fix annotations in Plotly +- allow saving notebook with plots as pdf from IJulia +- fix fillrange and ribbon for step recipes +- implement native ticks that respond to zoom +- fix bar plot with one bar +- contour labels and colorbar fixes +- interactive linked axis for PyPlot +- add `NamedTuple` syntax to group with named legend +- use bar recipe in Plotly +- implement categorical ticks + ## 0.15.0 - improve resolution of png output of GR with savefig() From 3753ab1b55449f52f57c28a105556711eea495c1 Mon Sep 17 00:00:00 2001 From: piever Date: Thu, 22 Mar 2018 20:37:27 +0000 Subject: [PATCH 617/720] increase version number for tests --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 748ef4a8..c1fa9601 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.15.0" +const _current_plots_version = v"0.15.1" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 8bc28d472fd0c85c18e37049a5044a88d89ce3c2 Mon Sep 17 00:00:00 2001 From: CarloLucibello Date: Sat, 24 Mar 2018 19:12:18 -0400 Subject: [PATCH 618/720] import filter --- src/Plots.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Plots.jl b/src/Plots.jl index 222270cb..d4f4c50f 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -15,6 +15,7 @@ using Base.Meta import Showoff import StatsBase import JSON +import Base.Iterators: filter using Requires From 4d8ef2a008635cc73dd68c3c77d7a1d44721c4a0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 27 Mar 2018 13:41:18 +0200 Subject: [PATCH 619/720] import mplot3d in pyplot --- src/backends/pyplot.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 24323e72..b5f21a23 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -84,6 +84,7 @@ function _initialize_backend(::PyPlotBackend) export PyPlot const pycolors = PyPlot.pyimport("matplotlib.colors") const pypath = PyPlot.pyimport("matplotlib.path") + const mplot3d = PyPlot.pyimport("mpl_toolkits.mplot3d") const pypatches = PyPlot.pyimport("matplotlib.patches") const pyfont = PyPlot.pyimport("matplotlib.font_manager") const pyticker = PyPlot.pyimport("matplotlib.ticker") From a5f7c1b8673b308e3215b74e873acbff764419c5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 27 Mar 2018 14:24:26 +0200 Subject: [PATCH 620/720] fix markercolor in legend for marker_z with st = :path --- 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 24323e72..a485fb75 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1255,7 +1255,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) linestyle = py_linestyle(:path,series[:linestyle]), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), - markerfacecolor = py_markercolor(series) + markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5]) ) else series[:serieshandle][1] From f56d944870d13ef56c14df74f99331b9639d22de Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 28 Mar 2018 11:32:23 +0200 Subject: [PATCH 621/720] hspan and vspan recipes --- src/Plots.jl | 2 ++ src/recipes.jl | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/Plots.jl b/src/Plots.jl index 222270cb..f1026810 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -187,6 +187,8 @@ include("output.jl") @shorthands sticks @shorthands hline @shorthands vline +@shorthands hspan +@shorthands vspan @shorthands ohlc @shorthands contour @shorthands contourf diff --git a/src/recipes.jl b/src/recipes.jl index bfe7d0b4..099d9b38 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -100,6 +100,30 @@ end end @deps vline straightline +@recipe function f(::Type{Val{:hspan}}, x, y, z) + n = div(length(y), 2) + newx = repeat([-Inf, Inf, Inf, -Inf, NaN], outer = n) + newy = vcat([[y[2i-1], y[2i-1], y[2i], y[2i], NaN] for i in 1:n]...) + linewidth --> 0 + x := newx + y := newy + seriestype := :shape + () +end +@deps hspan shape + +@recipe function f(::Type{Val{:vspan}}, x, y, z) + n = div(length(y), 2) + newx = vcat([[y[2i-1], y[2i-1], y[2i], y[2i], NaN] for i in 1:n]...) + newy = repeat([-Inf, Inf, Inf, -Inf, NaN], outer = n) + linewidth --> 0 + x := newx + y := newy + seriestype := :shape + () +end +@deps vspan shape + # --------------------------------------------------------------------------- # path and scatter From dd6842522f8d353dcd3825c0b1fb82b1b0258277 Mon Sep 17 00:00:00 2001 From: CarloLucibello Date: Wed, 28 Mar 2018 09:50:10 -0700 Subject: [PATCH 622/720] avoid import --- src/Plots.jl | 1 - src/backends/unicodeplots.jl | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index d4f4c50f..222270cb 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -15,7 +15,6 @@ using Base.Meta import Showoff import StatsBase import JSON -import Base.Iterators: filter using Requires diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 99482750..8be28b7f 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -162,7 +162,7 @@ function addUnicodeSeries!(o, d::KW, addlegend::Bool, xlim, ylim) color = d[:linecolor] in UnicodePlots.color_cycle ? d[:linecolor] : :auto # add the series - x, y = Plots.unzip(collect(filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y)))) + x, y = Plots.unzip(collect(Base.Iterators.filter(xy->isfinite(xy[1])&&isfinite(xy[2]), zip(x,y)))) func(o, x, y; color = color, name = label) end From b57abfd563866b9c94c88c49204c7ab7562ac863 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 31 Mar 2018 14:45:12 +0200 Subject: [PATCH 623/720] remove sp arg from get_linecolor and get_fillcolor --- src/backends/gr.jl | 14 +++++++------- src/utils.jl | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 2ab89c5d..648e55be 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1031,7 +1031,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) GR.setfillintstyle(GR.INTSTYLE_SOLID) fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng)) for (i, rng) in enumerate(segments_iterator) - gr_set_fillcolor(get_fillcolor(sp, series, i)) + gr_set_fillcolor(get_fillcolor(series, i)) fx = _cycle(x, vcat(rng, reverse(rng))) fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) @@ -1042,7 +1042,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st in (:path, :straightline) for (i, rng) in enumerate(segments_iterator) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x[rng], y[rng]; arrowside = arrowside) end @@ -1125,7 +1125,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) iter_segments(x, y, z) end for (i, rng) in enumerate(segments_iterator) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series, i)) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) GR.polyline3d(x[rng], y[rng], z[rng]) end end @@ -1196,11 +1196,11 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) xseg, yseg = x[rng], y[rng] # draw the interior - gr_set_fill(get_fillcolor(sp, series, i)) + gr_set_fill(get_fillcolor(series, i)) GR.fillarea(xseg, yseg) # draw the shapes - gr_set_line(series[:linewidth], :solid, get_linecolor(sp, series, i)) + gr_set_line(series[:linewidth], :solid, get_linecolor(series, i)) GR.polyline(xseg, yseg) end end @@ -1286,10 +1286,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(sp, series)) #, series[:linealpha]) + gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing - gr_set_fill(get_fillcolor(sp, series)) #, series[:fillalpha]) + gr_set_fill(get_fillcolor(series)) #, series[:fillalpha]) l, r = xpos-0.07, xpos-0.01 b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] diff --git a/src/utils.jl b/src/utils.jl index e8ded4ec..5ec52c4a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -602,26 +602,26 @@ function hascolorbar(sp::Subplot) hascbar end -function get_linecolor(sp::Subplot, series::Series, i::Int = 1) +function get_linecolor(series::Series, i::Int = 1) lc = series[:linecolor] lz = series[:line_z] if lz == nothing isa(lc, ColorGradient) ? lc : _cycle(lc, i) else - cmin, cmax = get_clims(sp) + cmin, cmax = get_clims(series[:subplot]) grad = isa(lc, ColorGradient) ? lc : cgrad() grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)] end end -function get_fillcolor(sp::Subplot, series::Series, i::Int = 1) +function get_fillcolor(series::Series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] lz = series[:line_z] if fz == nothing && lz == nothing isa(fc, ColorGradient) ? fc : _cycle(fc, i) else - cmin, cmax = get_clims(sp) + cmin, cmax = get_clims(series[:subplot]) grad = isa(fc, ColorGradient) ? fc : cgrad() if fz != nothing grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)] From 4bcf43c84b28e0870b5d1967e3e43b5733b484ac Mon Sep 17 00:00:00 2001 From: Christopher Rackauckas Date: Sat, 31 Mar 2018 09:11:02 -0700 Subject: [PATCH 624/720] Update imgcomp.jl --- test/imgcomp.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/imgcomp.jl b/test/imgcomp.jl index c1fa9601..d26d1635 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.15.1" +const _current_plots_version = v"0.16.0" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 1b5240a513b08ddda3d22b942c886088fd20c417 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 31 Mar 2018 18:18:58 +0200 Subject: [PATCH 625/720] introduce iter_segments(series::Series) considering certain vector series attributes --- src/backends/gr.jl | 18 +++++------------- src/utils.jl | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 648e55be..e60ea894 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1021,16 +1021,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st in (:path, :scatter, :straightline) if length(x) > 1 lz = series[:line_z] - segments_iterator = if lz != nothing && length(lz) > 1 - [i:(i + 1) for i in 1:(length(x) - 1)] - else - iter_segments(x, y) - end + segments = iter_segments(series) # do area fill if frng != nothing GR.setfillintstyle(GR.INTSTYLE_SOLID) fr_from, fr_to = (is_2tuple(frng) ? frng : (y, frng)) - for (i, rng) in enumerate(segments_iterator) + for (i, rng) in enumerate(segments) gr_set_fillcolor(get_fillcolor(series, i)) fx = _cycle(x, vcat(rng, reverse(rng))) fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) @@ -1041,7 +1037,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st in (:path, :straightline) - for (i, rng) in enumerate(segments_iterator) + for (i, rng) in enumerate(segments) gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x[rng], y[rng]; arrowside = arrowside) @@ -1119,12 +1115,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st == :path3d if length(x) > 1 lz = series[:line_z] - segments_iterator = if lz != nothing && length(lz) > 1 - [i:(i + 1) for i in 1:(length(x) - 1)] - else - iter_segments(x, y, z) - end - for (i, rng) in enumerate(segments_iterator) + segments = iter_segments(series) + for (i, rng) in enumerate(segments) gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) GR.polyline3d(x[rng], y[rng], z[rng]) end diff --git a/src/utils.jl b/src/utils.jl index 5ec52c4a..7b615759 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -192,6 +192,20 @@ function iter_segments(args...) SegmentsIterator(tup, n) end +function iter_segments(series::Series) + x, y, z = series[:x], series[:y], series[:z] + if has_attribute_segments(series) + return [i:(i + 1) for i in 1:(length(y) - 1)] + else + segs = UnitRange{Int64}[] + args = is3d(series) ? (x, y, z) : (x, y) + for seg in iter_segments(args...) + push!(segs, seg) + end + return segs + end +end + # helpers to figure out if there are NaN values in a list of array types anynan(i::Int, args::Tuple) = any(a -> !isfinite(_cycle(a,i)), args) anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) @@ -631,6 +645,18 @@ function get_fillcolor(series::Series, i::Int = 1) end end +function has_attribute_segments(series::Series) + # we want to check if a series needs to be split into segments just because + # of its attributes + for letter in (:x, :y, :z) + # If we have NaNs in the data they define the segments and + # SegmentsIterator is used + NaN in series[letter] && return false + end + # ... else we check relevant attributes if they have multiple inputs + return any((typeof(series[attr]) <: AbstractVector && length(series[attr] > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) +end + # --------------------------------------------------------------- makekw(; kw...) = KW(kw) From fc7b6dd0c6231f2af1c93e1b85c2ee495b30ab5f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 31 Mar 2018 18:41:43 +0200 Subject: [PATCH 626/720] some bug fixes --- src/utils.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 7b615759..252f9aed 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -651,10 +651,10 @@ function has_attribute_segments(series::Series) for letter in (:x, :y, :z) # If we have NaNs in the data they define the segments and # SegmentsIterator is used - NaN in series[letter] && return false + series[letter] != nothing && NaN in series[letter] && return false end # ... else we check relevant attributes if they have multiple inputs - return any((typeof(series[attr]) <: AbstractVector && length(series[attr] > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) + return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z)) end # --------------------------------------------------------------- From f89b1ba303fd4f40a392a023f3e3fcb3a05181c0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 00:41:13 +0200 Subject: [PATCH 627/720] implement vector arguments for GR and PyPlot --- src/args.jl | 16 +++--- src/backends/gr.jl | 65 +++++++++++---------- src/backends/pyplot.jl | 127 +++++++++++++++++++++-------------------- src/utils.jl | 17 ++++++ 4 files changed, 123 insertions(+), 102 deletions(-) diff --git a/src/args.jl b/src/args.jl index 68354760..a1df9264 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1450,18 +1450,18 @@ end # converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically -function getSeriesRGBColor(c, α, sp::Subplot, n::Int) +function getSeriesRGBColor(c, sp::Subplot, n::Int) if c == :auto c = autopick(sp[:color_palette], n) elseif isa(c, Int) c = autopick(sp[:color_palette], c) end - plot_color(c, α) + plot_color(c) end function ensure_gradient!(d::KW, csym::Symbol, asym::Symbol) if !isa(d[csym], ColorGradient) - d[csym] = cgrad(alpha = d[asym]) + d[csym] = typeof(d[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = d[asym]) end end @@ -1508,21 +1508,21 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) end # update series color - d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], d[:seriesalpha], sp, plotIndex) + d[:seriescolor] = getSeriesRGBColor.(d[:seriescolor], sp, plotIndex) # update other colors for s in (:line, :marker, :fill) csym, asym = Symbol(s,:color), Symbol(s,:alpha) d[csym] = if d[csym] == :auto - plot_color(if has_black_border_for_default(d[:seriestype]) && s == :line + plot_color.(if has_black_border_for_default(d[:seriestype]) && s == :line sp[:foreground_color_subplot] else d[:seriescolor] - end, d[asym]) + end) elseif d[csym] == :match - plot_color(d[:seriescolor], d[asym]) + plot_color.(d[:seriescolor]) else - getSeriesRGBColor(d[csym], d[asym], sp, plotIndex) + getSeriesRGBColor.(d[csym], sp, plotIndex) end end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e60ea894..f35866c9 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -135,7 +135,7 @@ const gr_font_family = Dict( # -------------------------------------------------------------------------------------- function gr_getcolorind(c) - GR.settransparency(float(alpha(c))) + gr_set_transparency(float(alpha(c))) convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c))) end @@ -143,6 +143,7 @@ gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(_cycle(c,1))) gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1))) gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1))) gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1))) +gr_set_transparency(α::Real) = GR.settransparency(clamp(α, 0, 1)) # -------------------------------------------------------------------------------------- @@ -230,7 +231,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw angular grid if xaxis[:grid] gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) for i in 1:length(α) GR.polyline([sinf[i], 0], [cosf[i], 0]) end @@ -239,7 +240,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw radial grid if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) for i in 1:length(rtick_values) r = (rtick_values[i] - rmin) / (rmax - rmin) if r <= 1.0 && r >= 0.0 @@ -250,7 +251,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) end #prepare to draw ticks - GR.settransparency(1) + gr_set_transparency(1) GR.setlinecolorind(90) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) @@ -319,9 +320,6 @@ function normalize_zvals(zv::AVec, clims::NTuple{2, <:Real}) end end -gr_alpha(α::Void) = 1 -gr_alpha(α::Real) = α - # --------------------------------------------------------- # draw ONE Shape @@ -369,7 +367,7 @@ function gr_draw_markers(series::Series, x, y, msize, mz) # pick a color from the pre-loaded gradient ci = round(Int, 1000 + _cycle(mz, i) * 255) cfuncind(ci) - GR.settransparency(_gr_gradient_alpha[ci-999]) + gr_set_transparency(_gr_gradient_alpha[ci-999]) end # don't draw filled area if marker shape is 1D if !(shape in (:hline, :vline, :+, :x)) @@ -794,21 +792,21 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if xaxis[:grid] gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) end if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) end if zaxis[:grid] gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid]) - GR.settransparency(zaxis[:gridalpha]) + gr_set_transparency(zaxis[:gridalpha]) GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) end gr_set_line(1, :solid, xaxis[:foreground_color_axis]) - GR.settransparency(1) + gr_set_transparency(1) GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) @@ -831,15 +829,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # gr_set_linecolor(sp[:foreground_color_grid]) # GR.grid(xtick, ytick, 0, 0, majorx, majory) gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) gr_polyline(coords(xgrid_segs)...) end if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) gr_polyline(coords(ygrid_segs)...) end - GR.settransparency(1.0) + gr_set_transparency(1.0) # axis lines if xaxis[:showaxis] @@ -858,7 +856,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if xaxis[:showaxis] if sp[:framestyle] in (:zerolines, :grid) gr_set_line(1, :solid, xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) else gr_set_line(1, :solid, xaxis[:foreground_color_axis]) end @@ -868,7 +866,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if yaxis[:showaxis] if sp[:framestyle] in (:zerolines, :grid) gr_set_line(1, :solid, yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) else gr_set_line(1, :solid, yaxis[:foreground_color_axis]) end @@ -920,10 +918,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) intensity = sp[:framestyle] == :semi ? 0.5 : 1.0 if sp[:framestyle] in (:box, :semi) gr_set_line(intensity, :solid, xaxis[:foreground_color_border]) - GR.settransparency(intensity) + gr_set_transparency(intensity) gr_polyline(coords(xborder_segs)...) gr_set_line(intensity, :solid, yaxis[:foreground_color_border]) - GR.settransparency(intensity) + gr_set_transparency(intensity) gr_polyline(coords(yborder_segs)...) end end @@ -1030,7 +1028,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_fillcolor(get_fillcolor(series, i)) fx = _cycle(x, vcat(rng, reverse(rng))) fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) - series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) + gr_set_transparency(get_fillalpha(series, i)) GR.fillarea(fx, fy) end end @@ -1038,7 +1036,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st in (:path, :straightline) for (i, rng) in enumerate(segments) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha]) + gr_set_transparency(get_linealpha(series, i)) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x[rng], y[rng]; arrowside = arrowside) end @@ -1064,8 +1063,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else - GR.setlinetype(gr_linetype[series[:linestyle]]) - GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) + GR.setlinetype(gr_linetype[get_linestyle(series)]) + GR.setlinewidth(max(0, get_linewidth(series) / (sum(gr_plot_size) * 0.001))) if plot_color(series[:linecolor]) == [plot_color(:black)] GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0)) else @@ -1117,7 +1116,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) lz = series[:line_z] segments = iter_segments(series) for (i, rng) in enumerate(segments) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha]) + gr_set_transparency(get_linealpha(series, i)) GR.polyline3d(x[rng], y[rng], z[rng]) end end @@ -1189,10 +1189,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the interior gr_set_fill(get_fillcolor(series, i)) + gr_set_transparency(get_fillalpha(series, i)) GR.fillarea(xseg, yseg) # draw the shapes - gr_set_line(series[:linewidth], :solid, get_linecolor(series, i)) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) + gr_set_transparency(get_linealpha(series, i)) GR.polyline(xseg, yseg) end end @@ -1224,7 +1226,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the colorbar if cmap && st != :contour # special colorbar with steps is drawn for contours gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - GR.settransparency(1) + gr_set_transparency(1) gr_colorbar(sp, clims) end @@ -1271,14 +1273,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if sp[:legendtitle] != nothing GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) gr_set_textcolor(sp[:legendfontcolor]) - GR.settransparency(1) + gr_set_transparency(1) gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) ypos -= dy end for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series)) #, series[:linealpha]) + gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing gr_set_fill(get_fillcolor(series)) #, series[:fillalpha]) @@ -1286,14 +1288,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] y = [b, b, t, t, b] - GR.settransparency(gr_alpha(series[:fillalpha])) + gr_set_transparency(get_fillalpha(series)) gr_polyline(x, y, GR.fillarea) - GR.settransparency(gr_alpha(series[:linealpha])) + gr_set_transparency(get_linealpha(series)) + gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series)) st == :shape && gr_polyline(x, y) end if st in (:path, :straightline) - GR.settransparency(gr_alpha(series[:linealpha])) + gr_set_transparency(get_linealpha(series)) if series[:fillrange] == nothing || series[:ribbon] != nothing GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) else diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index fe67ac7e..21c7b773 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -136,6 +136,7 @@ py_color(s) = py_color(parse(Colorant, string(s))) py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c)) py_color(cs::AVec) = map(py_color, cs) py_color(grad::ColorGradient) = py_color(grad.colors) +py_color(c::Colorant, α) = py_color(plot_color(c, α)) function py_colormap(grad::ColorGradient) pyvals = [(z, py_color(grad[z])) for z in grad.values] @@ -492,60 +493,49 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # line plot if st in (:path, :path3d, :steppre, :steppost, :straightline) - if series[:linewidth] > 0 - if series[:line_z] == nothing - handle = ax[:plot](xyargs...; - label = series[:label], - zorder = series[:series_plotindex], - color = py_linecolor(series), - linewidth = py_dpi_scale(plt, series[:linewidth]), - linestyle = py_linestyle(st, series[:linestyle]), - solid_capstyle = "round", - drawstyle = py_stepstyle(st) - )[1] - push!(handles, handle) - - else + if maximum(series[:linewidth]) > 0 + segments = iter_segments(series) + if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) # multicolored line segments - n = length(x) - 1 + n = length(segments) # segments = Array(Any,n) segments = [] kw = KW( :label => series[:label], :zorder => plt.n, :cmap => py_linecolormap(series), - :linewidth => py_dpi_scale(plt, series[:linewidth]), - :linestyle => py_linestyle(st, series[:linestyle]), + :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), + :linestyles => py_linestyle(st, get_linestyle(series, 1:n)), :norm => pycolors["Normalize"](; extrakw...) ) lz = _cycle(series[:line_z], 1:n) handle = if is3d(st) - for rng in iter_segments(x, y, z) - length(rng) < 2 && continue - for i in rng[1:end-1] - push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)), - (_cycle(x,i+1),_cycle(y,i+1),_cycle(z,i+1))]) - end - end - - lc = pyart3d["Line3DCollection"](segments; kw...) + line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments] + lc = pyart3d["Line3DCollection"](line_segments; kw...) lc[:set_array](lz) ax[:add_collection3d](lc, zs=z) #, zdir='y') lc else - for rng in iter_segments(x, y) - length(rng) < 2 && continue - for i in rng[1:end-1] - push!(segments, [(_cycle(x,i),_cycle(y,i)), (_cycle(x,i+1),_cycle(y,i+1))]) - end - end - - lc = pycollections["LineCollection"](segments; kw...) + line_segments = [[(x[j], y[j]) for j in rng] for rng in segments] + lc = pycollections["LineCollection"](line_segments; kw...) lc[:set_array](lz) ax[:add_collection](lc) lc end push!(handles, handle) + else + for (i, rng) in enumerate(iter_segments(series)) + handle = ax[:plot]((arg[rng] for arg in xyargs)...; + label = i == 1 ? series[:label] : "", + zorder = series[:series_plotindex], + color = py_color(get_linecolor(series, i), get_linealpha(series, i)), + linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linestyle = py_linestyle(st, get_linestyle(series, i)), + solid_capstyle = "round", + drawstyle = py_stepstyle(st) + )[1] + push!(handles, handle) + end end a = series[:arrow] @@ -559,8 +549,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :shrinkB => 0, :edgecolor => py_linecolor(series), :facecolor => py_linecolor(series), - :linewidth => py_dpi_scale(plt, series[:linewidth]), - :linestyle => py_linestyle(st, series[:linestyle]), + :linewidth => py_dpi_scale(plt, get_linewidth(series)), + :linestyle => py_linestyle(st, get_linestyle(series)), ) add_arrows(x, y) do xyprev, xy ax[:annotate]("", @@ -794,16 +784,17 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st == :shape handle = [] - for (i,rng) in enumerate(iter_segments(x, y)) + for (i, rng) in enumerate(iter_segments(series)) if length(rng) > 1 path = pypath["Path"](hcat(x[rng], y[rng])) patches = pypatches["PathPatch"]( path; label = series[:label], zorder = series[:series_plotindex], - edgecolor = py_color(_cycle(series[:linecolor], i)), - facecolor = py_color(_cycle(series[:fillcolor], i)), - linewidth = py_dpi_scale(plt, series[:linewidth]), + edgecolor = py_color(get_linecolor(series, i), get_linealpha(series, i)), + facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)), + linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linestyle = py_linestyle(st, get_linestyle(series, i)), fill = true ) push!(handle, ax[:add_patch](patches)) @@ -835,24 +826,26 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # handle area filling fillrange = series[:fillrange] if fillrange != nothing && st != :contour - f, dim1, dim2 = if isvertical(series) - :fill_between, x, y - else - :fill_betweenx, y, x - end - n = length(dim1) - args = if typeof(fillrange) <: Union{Real, AVec} - dim1, expand_data(fillrange, n), dim2 - elseif is_2tuple(fillrange) - dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) - end + for (i, rng) in enumerate(iter_segments(series)) + f, dim1, dim2 = if isvertical(series) + :fill_between, x[rng], y[rng] + else + :fill_betweenx, y[rng], x[rng] + end + n = length(dim1) + args = if typeof(fillrange) <: Union{Real, AVec} + dim1, expand_data(fillrange, n), dim2 + elseif is_2tuple(fillrange) + dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) + end - handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); - zorder = series[:series_plotindex], - facecolor = py_fillcolor(series), - linewidths = 0 - ) - push!(handles, handle) + handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); + zorder = series[:series_plotindex], + facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)), + linewidths = 0 + ) + push!(handles, handle) + end end # this is all we need to add the series_annotations text @@ -1020,6 +1013,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) kw[:ticks] = locator kw[:format] = formatter kw[:boundaries] = vcat(0, kw[:values] + 0.5) + elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z)) + cmin, cmax = get_clims(sp) + norm = pycolors[:Normalize](vmin = cmin, vmax = cmax) + f = colorbar_series[:line_z] != nothing ? py_linecolormap : py_fillcolormap + cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series)) + cmap[:set_array]([]) + handle = cmap end # create and store the colorbar object (handle) and the axis that it is drawn on. @@ -1250,15 +1250,16 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # add a line/marker and a label push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing pypatches[:Patch]( - edgecolor = py_color(_cycle(series[:linecolor],1)), - facecolor = py_color(_cycle(series[:fillcolor],1)), - linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), + edgecolor = py_color(get_linecolor(series), get_linealpha(series)), + facecolor = py_color(get_fillcolor(series), get_fillalpha(series)), + linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linestyle = py_linestyle(series[:seriestype], get_linestyle(series)) ) elseif series[:seriestype] in (:path, :straightline) PyPlot.plt[:Line2D]((0,1),(0,0), - color = py_color(_cycle(series[:linecolor],1)), - linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), - linestyle = py_linestyle(:path,series[:linestyle]), + color = py_color(get_linecolor(series), get_linealpha(series)), + linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linestyles = py_linestyle(:path, get_linestyle(series)), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5]) diff --git a/src/utils.jl b/src/utils.jl index 252f9aed..e2232936 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -628,6 +628,18 @@ function get_linecolor(series::Series, i::Int = 1) end end +function get_linealpha(series::Series, i::Int = 1) + _cycle(series[:linealpha], i) +end + +function get_linewidth(series::Series, i::Int = 1) + _cycle(series[:linewidth], i) +end + +function get_linestyle(series::Series, i::Int = 1) + _cycle(series[:linestyle], i) +end + function get_fillcolor(series::Series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] @@ -645,6 +657,10 @@ function get_fillcolor(series::Series, i::Int = 1) end end +function get_fillalpha(series::Series, i::Int = 1) + _cycle(series[:fillalpha], i) +end + function has_attribute_segments(series::Series) # we want to check if a series needs to be split into segments just because # of its attributes @@ -653,6 +669,7 @@ function has_attribute_segments(series::Series) # SegmentsIterator is used series[letter] != nothing && NaN in series[letter] && return false end + series[:seriestype] == :shape && return false # ... else we check relevant attributes if they have multiple inputs return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z)) end From c34e1d3c199958240e147f8aa996617c592da5ea Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 18:35:26 +0200 Subject: [PATCH 628/720] implement vector arguments, line_z and fill_z for plotly --- src/backends/plotly.jl | 259 ++++++++++++++++++++++++++++------------- 1 file changed, 176 insertions(+), 83 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 392b73e0..9d7126b0 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -30,7 +30,7 @@ const _plotly_attr = merge_with_base_supported([ :tickfont, :guidefont, :legendfont, :grid, :gridalpha, :gridlinewidth, :legend, :colorbar, :colorbar_title, - :marker_z, :fill_z, :levels, + :marker_z, :fill_z, :line_z, :levels, :ribbon, :quiver, :orientation, # :overwrite_figure, @@ -543,23 +543,8 @@ function plotly_series(plt::Plot, series::Series) end # set the "type" - if st in (:path, :scatter, :scattergl, :straightline) - d_out[:type] = st==:scattergl ? "scattergl" : "scatter" - d_out[:mode] = if hasmarker - hasline ? "lines+markers" : "markers" - else - hasline ? "lines" : "none" - end - if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple) - d_out[:fill] = "tozeroy" - d_out[:fillcolor] = rgba_string(series[:fillcolor]) - elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real} - d_out[:fill] = "tonexty" - d_out[:fillcolor] = rgba_string(series[:fillcolor]) - elseif !(series[:fillrange] in (false, nothing)) - warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])") - end - d_out[:x], d_out[:y] = x, y + if st in (:path, :scatter, :scattergl, :straightline, :path3d, :scatter3d) + return plotly_series_segments(series, d_out, x, y, z) elseif st == :heatmap d_out[:type] = "heatmap" @@ -583,7 +568,7 @@ function plotly_series(plt::Plot, series::Series) d_out[:hidesurface] = true wirelines = KW( :show => true, - :color => rgba_string(series[:linecolor]), + :color => rgba_string(plot_color(series[:linecolor], series[:linealpha])), :highlightwidth => series[:linewidth], ) d_out[:contours] = KW(:x => wirelines, :y => wirelines, :z => wirelines) @@ -603,15 +588,6 @@ function plotly_series(plt::Plot, series::Series) d_out[:values] = y d_out[:hoverinfo] = "label+percent+name" - elseif st in (:path3d, :scatter3d) - d_out[:type] = "scatter3d" - d_out[:mode] = if hasmarker - hasline ? "lines+markers" : "markers" - else - hasline ? "lines" : "none" - end - d_out[:x], d_out[:y], d_out[:z] = x, y, z - else warn("Plotly: seriestype $st isn't supported.") return KW() @@ -646,61 +622,15 @@ function plotly_series(plt::Plot, series::Series) end end - # add "line" - if hasline - d_out[:line] = KW( - :color => rgba_string(series[:linecolor]), - :width => series[:linewidth], - :shape => if st == :steppre - "vh" - elseif st == :steppost - "hv" - else - "linear" - end, - :dash => string(series[:linestyle]), - # :dash => "solid", - ) - end - plotly_polar!(d_out, series) plotly_hover!(d_out, series[:hover]) - if hasfillrange - # if hasfillrange is true, return two dictionaries (one for original - # series, one for series being filled to) instead of one - d_out_fillrange = deepcopy(d_out) - d_out_fillrange[:showlegend] = false - # if fillrange is provided as real or tuple of real, expand to array - if typeof(series[:fillrange]) <: Real - series[:fillrange] = fill(series[:fillrange], length(series[:x])) - elseif typeof(series[:fillrange]) <: Tuple - f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(series[:x])) : series[:fillrange][1] - f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(series[:x])) : series[:fillrange][2] - series[:fillrange] = (f1, f2) - end - if isa(series[:fillrange], AbstractVector) - d_out_fillrange[:y] = series[:fillrange] - delete!(d_out_fillrange, :fill) - delete!(d_out_fillrange, :fillcolor) - else - # if fillrange is a tuple with upper and lower limit, d_out_fillrange - # is the series that will do the filling - d_out_fillrange[:x], d_out_fillrange[:y] = - concatenate_fillrange(series[:x], series[:fillrange]) - d_out_fillrange[:line][:width] = 0 - delete!(d_out, :fill) - delete!(d_out, :fillcolor) - end - - return [d_out_fillrange, d_out] - else - return [d_out] - end + return [d_out] end function plotly_series_shapes(plt::Plot, series::Series) - d_outs = [] + segments = iter_segments(series) + d_outs = Vector{KW}(length(segments)) # TODO: create a d_out for each polygon # x, y = series[:x], series[:y] @@ -714,7 +644,7 @@ function plotly_series_shapes(plt::Plot, series::Series) # base_d[:legendgroup] = series[:label] x, y = shape_data(series) - for (i,rng) in enumerate(iter_segments(x,y)) + for (i,rng) in enumerate(segments) length(rng) < 2 && continue # to draw polygons, we actually draw lines with fill @@ -724,23 +654,186 @@ function plotly_series_shapes(plt::Plot, series::Series) :x => vcat(x[rng], x[rng[1]]), :y => vcat(y[rng], y[rng[1]]), :fill => "tozeroy", - :fillcolor => rgba_string(_cycle(series[:fillcolor], i)), + :fillcolor => rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i))), )) if series[:markerstrokewidth] > 0 d_out[:line] = KW( - :color => rgba_string(_cycle(series[:linecolor], i)), - :width => series[:linewidth], - :dash => string(series[:linestyle]), + :color => rgba_string(plot_color(get_linecolor(series, i), get_linealpha(series, i))), + :width => get_linewidth(series, i), + :dash => string(get_linestyle(series, i)), ) end d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false plotly_polar!(d_out, series) plotly_hover!(d_out, _cycle(series[:hover], i)) - push!(d_outs, d_out) + d_outs[i] = d_out + end + if series[:fill_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, base_d, :line)) end d_outs end +function plotly_series_segments(series::Series, d_base::KW, x, y, z) + st = series[:seriestype] + sp = series[:subplot] + isscatter = st in (:scatter, :scatter3d, :scattergl) + hasmarker = isscatter || series[:markershape] != :none + hasline = st in (:path, :path3d, :straightline) + hasfillrange = st in (:path, :scatter, :scattergl, :straightline) && + (isa(series[:fillrange], AbstractVector) || isa(series[:fillrange], Tuple)) + + segments = iter_segments(series) + d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments)) + + for (i,rng) in enumerate(segments) + length(rng) < 2 && continue + + d_out = deepcopy(d_base) + d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false + + # set the type + if st in (:path, :scatter, :scattergl, :straightline) + d_out[:type] = st==:scattergl ? "scattergl" : "scatter" + d_out[:mode] = if hasmarker + hasline ? "lines+markers" : "markers" + else + hasline ? "lines" : "none" + end + if series[:fillrange] == true || series[:fillrange] == 0 || isa(series[:fillrange], Tuple) + d_out[:fill] = "tozeroy" + d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i))) + elseif typeof(series[:fillrange]) <: Union{AbstractVector{<:Real}, Real} + d_out[:fill] = "tonexty" + d_out[:fillcolor] = rgba_string(plot_color(get_fillcolor(series, i), get_fillalpha(series, i))) + elseif !(series[:fillrange] in (false, nothing)) + warn("fillrange ignored... plotly only supports filling to zero and to a vector of values. fillrange: $(series[:fillrange])") + end + d_out[:x], d_out[:y] = x[rng], y[rng] + + elseif st in (:path3d, :scatter3d) + d_out[:type] = "scatter3d" + d_out[:mode] = if hasmarker + hasline ? "lines+markers" : "markers" + else + hasline ? "lines" : "none" + end + d_out[:x], d_out[:y], d_out[:z] = x[rng], y[rng], z[rng] + end + + # add "marker" + if hasmarker + d_out[:marker] = KW( + :symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])), + # :opacity => series[:markeralpha], + :size => 2 * series[:markersize], + # :color => rgba_string(series[:markercolor]), + :line => KW( + :color => _cycle(rgba_string.(series[:markerstrokecolor]), eachindex(rng)), + :width => series[:markerstrokewidth], + ), + ) + + # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient + if series[:marker_z] == nothing + d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]), eachindex(rng)) + else + # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) + # grad = as_gradient(series[:markercolor], series[:markeralpha]) + cmin, cmax = get_clims(sp) + # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) + d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in _cycle(series[:marker_z], rng)] + d_out[:marker][:cmin] = cmin + d_out[:marker][:cmax] = cmax + d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha]) + d_out[:marker][:showscale] = hascolorbar(sp) + end + end + + # add "line" + if hasline + d_out[:line] = KW( + :color => rgba_string(plot_color(get_linecolor(series, i), get_linealpha(series, i))), + :width => get_linewidth(series, i), + :shape => if st == :steppre + "vh" + elseif st == :steppost + "hv" + else + "linear" + end, + :dash => string(get_linestyle(series, i)), + ) + end + + plotly_polar!(d_out, series) + plotly_hover!(d_out, series[:hover]) + + if hasfillrange + # if hasfillrange is true, return two dictionaries (one for original + # series, one for series being filled to) instead of one + d_out_fillrange = deepcopy(d_out) + d_out_fillrange[:showlegend] = false + # if fillrange is provided as real or tuple of real, expand to array + if typeof(series[:fillrange]) <: Real + series[:fillrange] = fill(series[:fillrange], length(rng)) + elseif typeof(series[:fillrange]) <: Tuple + f1 = typeof(series[:fillrange][1]) <: Real ? fill(series[:fillrange][1], length(rng)) : series[:fillrange][1][rng] + f2 = typeof(series[:fillrange][2]) <: Real ? fill(series[:fillrange][2], length(rng)) : series[:fillrange][2][rng] + series[:fillrange] = (f1, f2) + end + if isa(series[:fillrange], AbstractVector) + d_out_fillrange[:y] = series[:fillrange] + delete!(d_out_fillrange, :fill) + delete!(d_out_fillrange, :fillcolor) + else + # if fillrange is a tuple with upper and lower limit, d_out_fillrange + # is the series that will do the filling + d_out_fillrange[:x], d_out_fillrange[:y] = + concatenate_fillrange(x[rng], series[:fillrange][rng]) + d_out_fillrange[:line][:width] = 0 + delete!(d_out, :fill) + delete!(d_out, :fillcolor) + end + + d_outs[(2 * i - 1):(2 * i)] = [d_out_fillrange, d_out] + else + d_outs[i] = d_out + end + end + + if series[:line_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, d_base, :line)) + elseif series[:fill_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, d_base, :fill)) + end + + d_outs +end + +function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol) + d_out = deepcopy(d_base) + cmin, cmax = get_clims(series[:subplot]) + d_out[:showlegend] = false + d_out[:type] = is3d(series) ? :scatter3d : :scatter + d_out[:mode] = :markers + d_out[:x], d_out[:y] = [series[:x][1]], [series[:y][1]] + if is3d(series) + d_out[:z] = [series[:z][1]] + end + # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) + d_out[:marker] = KW( + :size => 0, + :color => [0.5], + :cmin => cmin, + :cmax => cmax, + :colorscale => plotly_colorscale(series[Symbol("$(sym)color")], 1), + :showscale => hascolorbar(series[:subplot]), + ) + return d_out +end + + function plotly_polar!(d_out::KW, series::Series) # convert polar plots x/y to theta/radius if ispolar(series[:subplot]) From 55e9c8c9ebdf9b77ee773b5882a40de387473980 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 21:39:45 +0200 Subject: [PATCH 629/720] implement fillrange, vector arguments, line_z and fill_z for pgfplots --- src/args.jl | 2 +- src/backends/pgfplots.jl | 174 +++++++++++++++++++++++++++------------ src/utils.jl | 12 +-- 3 files changed, 128 insertions(+), 60 deletions(-) diff --git a/src/args.jl b/src/args.jl index a1df9264..6616dc1c 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1530,7 +1530,7 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) d[:markerstrokecolor] = if d[:markerstrokecolor] == :match plot_color(sp[:foreground_color_subplot], d[:markerstrokealpha]) else - getSeriesRGBColor(d[:markerstrokecolor], d[:markerstrokealpha], sp, plotIndex) + getSeriesRGBColor(plot_color(d[:markerstrokecolor], d[:markerstrokealpha]), sp, plotIndex) end # if marker_z, fill_z or line_z are set, ensure we have a gradient diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index bda7ac16..180640a1 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -148,33 +148,47 @@ function pgf_colormap(grad::ColorGradient) end,", ") end -function pgf_fillstyle(d::KW) - cstr,a = pgf_color(d[:fillcolor]) +function pgf_fillstyle(d, i = 1) + cstr,a = pgf_color(get_fillcolor(d, i)) + fa = get_fillalpha(d, i) + if fa != nothing + a = fa + end "fill = $cstr, fill opacity=$a" end -function pgf_linestyle(d::KW) - cstr,a = pgf_color(d[:linecolor]) +function pgf_linestyle(d, i = 1) + cstr,a = pgf_color(get_linecolor(d, i)) + la = get_linealpha(d, i) + if la != nothing + a = la + end """ color = $cstr, draw opacity=$a, - line width=$(d[:linewidth]), - $(get(_pgfplots_linestyles, d[:linestyle], "solid"))""" + line width=$(get_linewidth(d, i)), + $(get(_pgfplots_linestyles, get_linestyle(d, i), "solid"))""" end -function pgf_marker(d::KW) - shape = d[:markershape] - cstr, a = pgf_color(d[:markercolor]) - cstr_stroke, a_stroke = pgf_color(d[:markerstrokecolor]) +function pgf_marker(d, i = 1) + shape = _cycle(d[:markershape], i) + cstr, a = pgf_color(_cycle(d[:markercolor], i)) + if d[:markeralpha] != nothing + a = _cycle(d[:markeralpha], i) + end + cstr_stroke, a_stroke = pgf_color(_cycle(d[:markerstrokecolor], i)) + if d[:markerstrokealpha] != nothing + a_stroke = _cycle(d[:markerstrokealpha], i) + end """ mark = $(get(_pgfplots_markers, shape, "*")), - mark size = $(0.5 * d[:markersize]), + mark size = $(0.5 * _cycle(d[:markersize], i)), mark options = { color = $cstr_stroke, draw opacity = $a_stroke, fill = $cstr, fill opacity = $a, - line width = $(d[:markerstrokewidth]), + line width = $(_cycle(d[:markerstrokewidth], i)), rotate = $(shape == :dtriangle ? 180 : 0), - $(get(_pgfplots_linestyles, d[:markerstrokestyle], "solid")) + $(get(_pgfplots_linestyles, _cycle(d[:markerstrokestyle], i), "solid")) }""" end @@ -196,27 +210,10 @@ end function pgf_series(sp::Subplot, series::Series) d = series.d st = d[:seriestype] - style = [] - kw = KW() - push!(style, pgf_linestyle(d)) - push!(style, pgf_marker(d)) - - if d[:fillrange] != nothing || st in (:shape,) - push!(style, pgf_fillstyle(d)) - end - - # add to legend? - if sp[:legend] != :none && should_add_to_legend(series) - kw[:legendentry] = d[:label] - if st == :shape || d[:fillrange] != nothing - push!(style, "area legend") - end - else - push!(style, "forget plot") - end + series_collection = PGFPlots.Plot[] # function args - args = if st == :contour + args = if st == :contour d[:z].surf, d[:x], d[:y] elseif is3d(st) d[:x], d[:y], d[:z] @@ -241,31 +238,102 @@ function pgf_series(sp::Subplot, series::Series) else a end, args) - # for (i,a) in enumerate(args) - # if typeof(a) <: AbstractVector && typeof(a) != Vector - # args[i] = collect(a) - # end - # end - # include additional style, then add to the kw + if st in (:contour, :histogram2d) + style = [] + kw = KW() + push!(style, pgf_linestyle(d)) + push!(style, pgf_marker(d)) + push!(style, "forget plot") + + kw[:style] = join(style, ',') + func = if st == :histogram2d + PGFPlots.Histogram2 + else + PGFPlots.Contour + end + push!(series_collection, func(args...; kw...)) + + else + # series segments + segments = iter_segments(series) + for (i, rng) in enumerate(segments) + style = [] + kw = KW() + push!(style, pgf_linestyle(d, i)) + push!(style, pgf_marker(d, i)) + + if st == :shape + push!(style, pgf_fillstyle(d, i)) + end + + # add to legend? + if i == 1 && sp[:legend] != :none && should_add_to_legend(series) + kw[:legendentry] = d[:label] + if st == :shape # || d[:fillrange] != nothing + push!(style, "area legend") + end + else + push!(style, "forget plot") + end + + seg_args = (arg[rng] for arg in args) + + # include additional style, then add to the kw + if haskey(_pgf_series_extrastyle, st) + push!(style, _pgf_series_extrastyle[st]) + end + kw[:style] = join(style, ',') + + # add fillrange + if series[:fillrange] != nothing && st != :shape + push!(series_collection, pgf_fillrange_series(series, i, _cycle(series[:fillrange], rng), seg_args...)) + end + + # build/return the series object + func = if st == :path3d + PGFPlots.Linear3 + elseif st == :scatter + PGFPlots.Scatter + else + PGFPlots.Linear + end + push!(series_collection, func(seg_args...; kw...)) + end + end + series_collection +end + +function pgf_fillrange_series(series, i, fillrange, args...) + st = series[:seriestype] + style = [] + kw = KW() + push!(style, "line width = 0") + push!(style, "draw opacity = 0") + push!(style, pgf_fillstyle(series, i)) + push!(style, pgf_marker(series, i)) + push!(style, "forget plot") if haskey(_pgf_series_extrastyle, st) push!(style, _pgf_series_extrastyle[st]) end kw[:style] = join(style, ',') + func = is3d(series) ? PGFPlots.Linear3 : PGFPlots.Linear + return func(pgf_fillrange_args(fillrange, args...)...; kw...) +end - # build/return the series object - func = if st == :path3d - PGFPlots.Linear3 - elseif st == :scatter - PGFPlots.Scatter - elseif st == :histogram2d - PGFPlots.Histogram2 - elseif st == :contour - PGFPlots.Contour - else - PGFPlots.Linear - end - func(args...; kw...) +function pgf_fillrange_args(fillrange, x, y) + n = length(x) + x_fill = [x; x[n:-1:1]; x[1]] + y_fill = [y; _cycle(fillrange, n:-1:1); y[1]] + return x_fill, y_fill +end + +function pgf_fillrange_args(fillrange, x, y, z) + n = length(x) + x_fill = [x; x[n:-1:1]; x[1]] + y_fill = [y; y[n:-1:1]; x[1]] + z_fill = [z; _cycle(fillrange, n:-1:1); z[1]] + return x_fill, y_fill, z_fill end @@ -438,7 +506,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # As it is likely that all series within the same axis use the same # colormap this should not cause any problem. for series in series_list(sp) - for col in (:markercolor, :fillcolor) + for col in (:markercolor, :fillcolor, :linecolor) if typeof(series.d[col]) == ColorGradient push!(style,"colormap={plots}{$(pgf_colormap(series.d[col]))}") @@ -458,7 +526,7 @@ 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)) + push!.(o, pgf_series(sp, series)) # add series annotations anns = series[:series_annotations] diff --git a/src/utils.jl b/src/utils.jl index e2232936..8b957ca7 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -616,7 +616,7 @@ function hascolorbar(sp::Subplot) hascbar end -function get_linecolor(series::Series, i::Int = 1) +function get_linecolor(series, i::Int = 1) lc = series[:linecolor] lz = series[:line_z] if lz == nothing @@ -628,19 +628,19 @@ function get_linecolor(series::Series, i::Int = 1) end end -function get_linealpha(series::Series, i::Int = 1) +function get_linealpha(series, i::Int = 1) _cycle(series[:linealpha], i) end -function get_linewidth(series::Series, i::Int = 1) +function get_linewidth(series, i::Int = 1) _cycle(series[:linewidth], i) end -function get_linestyle(series::Series, i::Int = 1) +function get_linestyle(series, i::Int = 1) _cycle(series[:linestyle], i) end -function get_fillcolor(series::Series, i::Int = 1) +function get_fillcolor(series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] lz = series[:line_z] @@ -657,7 +657,7 @@ function get_fillcolor(series::Series, i::Int = 1) end end -function get_fillalpha(series::Series, i::Int = 1) +function get_fillalpha(series, i::Int = 1) _cycle(series[:fillalpha], i) end From d7b2173066d5ae46d2601e590e2a60d3adec33be Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 22:08:00 +0200 Subject: [PATCH 630/720] fix linestyle in pyplot --- src/backends/pyplot.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 21c7b773..47ae5170 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -495,7 +495,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st in (:path, :path3d, :steppre, :steppost, :straightline) if maximum(series[:linewidth]) > 0 segments = iter_segments(series) - if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) + if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector) # multicolored line segments n = length(segments) # segments = Array(Any,n) @@ -505,7 +505,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :zorder => plt.n, :cmap => py_linecolormap(series), :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), - :linestyles => py_linestyle(st, get_linestyle(series, 1:n)), + :linestyle => py_linestyle(st, get_linestyle.(series)), :norm => pycolors["Normalize"](; extrakw...) ) lz = _cycle(series[:line_z], 1:n) @@ -1259,7 +1259,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(get_linecolor(series), get_linealpha(series)), linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), - linestyles = py_linestyle(:path, get_linestyle(series)), + linestyle = py_linestyle(:path, get_linestyle(series)), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5]) From 7e4635de26b71033855a9c92dc3d7189abcb7603 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 22:11:22 +0200 Subject: [PATCH 631/720] fix transparency on GR --- src/backends/gr.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index f35866c9..cf369f64 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -144,6 +144,7 @@ gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1))) gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1))) gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1))) gr_set_transparency(α::Real) = GR.settransparency(clamp(α, 0, 1)) +function gr_set_transparency(::Void) end # -------------------------------------------------------------------------------------- From d1d7fd258f6b53a77d2477281cda7a4006365d8f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 22:14:50 +0200 Subject: [PATCH 632/720] add fill_z and line_z to supported pgfplots attr --- 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 180640a1..1dd2b272 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -27,7 +27,7 @@ const _pgfplots_attr = merge_with_base_supported([ :tickfont, :guidefont, :legendfont, :grid, :legend, :colorbar, - :marker_z, #:levels, + :fill_z, :line_z, :marker_z, #:levels, # :ribbon, :quiver, :arrow, # :orientation, # :overwrite_figure, From 777642ef55cae1867783bb1965b020d22b4d5603 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 22:44:29 +0200 Subject: [PATCH 633/720] pyplot use linecollection only WITHOUT fillrange --- 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 47ae5170..9c107fdb 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -495,7 +495,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st in (:path, :path3d, :steppre, :steppost, :straightline) if maximum(series[:linewidth]) > 0 segments = iter_segments(series) - if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector) + if length(segments) > 1 && (!any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector) # multicolored line segments n = length(segments) # segments = Array(Any,n) From a6f11cdb31af10aa7290d07c9564c28c0b472c67 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 23:21:57 +0200 Subject: [PATCH 634/720] fix pyplot (leave commented lines for possible future work) --- src/backends/pyplot.jl | 61 +++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 30 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 9c107fdb..cdf63b46 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -495,35 +495,36 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st in (:path, :path3d, :steppre, :steppost, :straightline) if maximum(series[:linewidth]) > 0 segments = iter_segments(series) - if length(segments) > 1 && (!any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector) - # multicolored line segments - n = length(segments) - # segments = Array(Any,n) - segments = [] - kw = KW( - :label => series[:label], - :zorder => plt.n, - :cmap => py_linecolormap(series), - :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), - :linestyle => py_linestyle(st, get_linestyle.(series)), - :norm => pycolors["Normalize"](; extrakw...) - ) - lz = _cycle(series[:line_z], 1:n) - handle = if is3d(st) - line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments] - lc = pyart3d["Line3DCollection"](line_segments; kw...) - lc[:set_array](lz) - ax[:add_collection3d](lc, zs=z) #, zdir='y') - lc - else - line_segments = [[(x[j], y[j]) for j in rng] for rng in segments] - lc = pycollections["LineCollection"](line_segments; kw...) - lc[:set_array](lz) - ax[:add_collection](lc) - lc - end - push!(handles, handle) - else + # TODO: check LineCollection alternative for speed + # if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) && !(typeof(series[:linestyle]) <: AbstractVector) + # # multicolored line segments + # n = length(segments) + # # segments = Array(Any,n) + # segments = [] + # kw = KW( + # :label => series[:label], + # :zorder => plt.n, + # :cmap => py_linecolormap(series), + # :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), + # :linestyle => py_linestyle(st, get_linestyle.(series)), + # :norm => pycolors["Normalize"](; extrakw...) + # ) + # lz = _cycle(series[:line_z], 1:n) + # handle = if is3d(st) + # line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments] + # lc = pyart3d["Line3DCollection"](line_segments; kw...) + # lc[:set_array](lz) + # ax[:add_collection3d](lc, zs=z) #, zdir='y') + # lc + # else + # line_segments = [[(x[j], y[j]) for j in rng] for rng in segments] + # lc = pycollections["LineCollection"](line_segments; kw...) + # lc[:set_array](lz) + # ax[:add_collection](lc) + # lc + # end + # push!(handles, handle) + # else for (i, rng) in enumerate(iter_segments(series)) handle = ax[:plot]((arg[rng] for arg in xyargs)...; label = i == 1 ? series[:label] : "", @@ -536,7 +537,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) )[1] push!(handles, handle) end - end + # end a = series[:arrow] if a != nothing && !is3d(st) # TODO: handle 3d later From 9b9a775a4189894834e840c0ed82b799df73b3b0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 3 Apr 2018 18:43:18 +0200 Subject: [PATCH 635/720] fix test errors --- src/utils.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 8b957ca7..80d5487f 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -667,7 +667,7 @@ function has_attribute_segments(series::Series) for letter in (:x, :y, :z) # If we have NaNs in the data they define the segments and # SegmentsIterator is used - series[letter] != nothing && NaN in series[letter] && return false + series[letter] != nothing && NaN in collect(series[letter]) && return false end series[:seriestype] == :shape && return false # ... else we check relevant attributes if they have multiple inputs From e30f4652afa159dc49a4720140b30c69387c8eab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hamza=20Yusuf=20=C3=87ak=C4=B1r?= <32282514+hycakir@users.noreply.github.com> Date: Thu, 5 Apr 2018 02:53:50 +0300 Subject: [PATCH 636/720] Remove SVG support, which is not there plotly backend does not support SVG output. What it shows is the HTML output of Plotly backend. This commit makes the request for SVG output to return an error as in PNG. --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9d7126b0..8578b32e 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -908,7 +908,7 @@ function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend}) end function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend}) - write(io, html_head(plt) * html_body(plt)) + error("svg output from the plotly backend is not supported. Please use plotlyjs instead.") end function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) From 6ca8471c64a45526ca45757f2bda388721bec82f Mon Sep 17 00:00:00 2001 From: "Michael K. Borregaard" Date: Fri, 6 Apr 2018 09:08:53 +0200 Subject: [PATCH 637/720] Improve histogram2d bin estimation The existing one would error when the correlation was high --- src/recipes.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 099d9b38..75075d02 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -562,7 +562,7 @@ function _auto_binning_nbins(vs::NTuple{N,AbstractVector}, dim::Integer; mode::S # The nd estimator is the key to most automatic binning methods, and is modified for twodimensional histograms to include correlation nd = n_samples^(1/(2+N)) - nd = N == 2 ? nd / (1-cor(first(vs), last(vs))^2)^(3//8) : nd # the >2-dimensional case does not have a nice solution to correlations + nd = N == 2 ? min(n_samples^(1/(2+N)), nd / (1-cor(first(vs), last(vs))^2)^(3//8)) : nd # the >2-dimensional case does not have a nice solution to correlations v = vs[dim] From 685e2eaff7c3645c5ba5ae724e47fd0cac086e49 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 6 Apr 2018 10:32:45 +0200 Subject: [PATCH 638/720] implement heatmapr recipe --- src/recipes.jl | 28 ++++++++++++++++++++++++++++ src/series.jl | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/recipes.jl b/src/recipes.jl index 099d9b38..3ece3f9c 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -389,6 +389,34 @@ end end @deps bar shape +# --------------------------------------------------------------------------- +# Heatmap +@recipe function f(::Type{Val{:heatmapr}}, x, y, z) + xe, ye = heatmap_edges(x), heatmap_edges(y) + m, n = size(z.surf) + x_pts, y_pts = fill(NaN, 6 * m * n), fill(NaN, 6 * m * n) + fz = zeros(m * n) + for i in 1:m # y + for j in 1:n # x + k = (j - 1) * m + i + inds = (6 * (k - 1) + 1):(6 * k - 1) + x_pts[inds] .= [xe[j], xe[j + 1], xe[j + 1], xe[j], xe[j]] + y_pts[inds] .= [ye[i], ye[i], ye[i + 1], ye[i + 1], ye[i]] + fz[k] = z.surf[i, j] + end + end + ensure_gradient!(plotattributes, :fillcolor, :fillalpha) + fill_z := fz + linewidth := 0 + linecolor := invisible() + x := x_pts + y := y_pts + z := nothing + seriestype := :shape + label := "" + () +end +@deps heatmapr shape # --------------------------------------------------------------------------- # Histograms diff --git a/src/series.jl b/src/series.jl index 1a502cc5..4c8607fd 100644 --- a/src/series.jl +++ b/src/series.jl @@ -8,7 +8,7 @@ const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} -all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image), get(d, :seriestype, :none)) +all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :heatmapr), get(d, :seriestype, :none)) # unknown convertToAnyVector(x, d::KW) = error("No user recipe defined for $(typeof(x))") From e498d091cd553c92d4e20287ac91d4250d762f89 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 6 Apr 2018 17:14:19 +0200 Subject: [PATCH 639/720] filled legend marker for filled area in PGFPlots --- src/backends/pgfplots.jl | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 1dd2b272..6c8929a5 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -269,9 +269,14 @@ function pgf_series(sp::Subplot, series::Series) # add to legend? if i == 1 && sp[:legend] != :none && should_add_to_legend(series) - kw[:legendentry] = d[:label] - if st == :shape # || d[:fillrange] != nothing - push!(style, "area legend") + if d[:fillrange] != nothing + # we add a series + push!(series_collection, pgf_fill_legend_hack(d, args)) + else + kw[:legendentry] = d[:label] + if st == :shape # || d[:fillrange] != nothing + push!(style, "area legend") + end end else push!(style, "forget plot") @@ -336,6 +341,25 @@ function pgf_fillrange_args(fillrange, x, y, z) return x_fill, y_fill, z_fill end +function pgf_fill_legend_hack(d, args) + style = [] + kw = KW() + push!(style, pgf_linestyle(d, 1)) + push!(style, pgf_marker(d, 1)) + push!(style, pgf_fillstyle(d, 1)) + push!(style, "area legend") + kw[:legendentry] = d[:label] + kw[:style] = join(style, ',') + st = d[:seriestype] + func = if st == :path3d + PGFPlots.Linear3 + elseif st == :scatter + PGFPlots.Scatter + else + PGFPlots.Linear + end + return func(([arg[1]] for arg in args)...; kw...) +end # ---------------------------------------------------------------- From 5a07c4917ef781ad576a037fa631848b7acc219a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 6 Apr 2018 18:37:57 +0200 Subject: [PATCH 640/720] fix multiple series --- 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 6c8929a5..51eb2565 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -270,7 +270,7 @@ function pgf_series(sp::Subplot, series::Series) # add to legend? if i == 1 && sp[:legend] != :none && should_add_to_legend(series) if d[:fillrange] != nothing - # we add a series + push!(style, "forget plot") push!(series_collection, pgf_fill_legend_hack(d, args)) else kw[:legendentry] = d[:label] From ad55551819848b2a34683f61b22abc601be6869a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 7 Apr 2018 08:55:52 +0200 Subject: [PATCH 641/720] allow to set the theme in PLOTS_DEFAULTS --- src/Plots.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Plots.jl b/src/Plots.jl index f1026810..8cf0f564 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -296,8 +296,11 @@ const CURRENT_BACKEND = CurrentBackend(:none) # for compatibility with Requires.jl: @init begin if isdefined(Main, :PLOTS_DEFAULTS) + if haskey(Main.PLOTS_DEFAULTS, :theme) + theme(Main.PLOTS_DEFAULTS[:theme]) + end for (k,v) in Main.PLOTS_DEFAULTS - default(k, v) + k == :theme || default(k, v) end end end From 8e3bd07c9111348126a5640751882594a71f7c86 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 7 Apr 2018 14:37:15 +0200 Subject: [PATCH 642/720] set line_z --- src/recipes.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/recipes.jl b/src/recipes.jl index 3ece3f9c..82efc3fa 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -407,8 +407,7 @@ end end ensure_gradient!(plotattributes, :fillcolor, :fillalpha) fill_z := fz - linewidth := 0 - linecolor := invisible() + line_z --> fz x := x_pts y := y_pts z := nothing From 7a702489d03b6b1345450682c8758cafbd783e1d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 7 Apr 2018 15:54:06 +0200 Subject: [PATCH 643/720] fixes for plotly --- src/backends/plotly.jl | 2 ++ src/recipes.jl | 2 +- src/utils.jl | 9 ++------- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 9d7126b0..eda984c9 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -669,6 +669,8 @@ function plotly_series_shapes(plt::Plot, series::Series) d_outs[i] = d_out end if series[:fill_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, base_d, :fill)) + elseif series[:line_z] != nothing push!(d_outs, plotly_colorbar_hack(series, base_d, :line)) end d_outs diff --git a/src/recipes.jl b/src/recipes.jl index 82efc3fa..611c8407 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -407,7 +407,7 @@ end end ensure_gradient!(plotattributes, :fillcolor, :fillalpha) fill_z := fz - line_z --> fz + line_z := fz x := x_pts y := y_pts z := nothing diff --git a/src/utils.jl b/src/utils.jl index 80d5487f..b9ab6705 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -643,17 +643,12 @@ end function get_fillcolor(series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] - lz = series[:line_z] - if fz == nothing && lz == nothing + if fz == nothing isa(fc, ColorGradient) ? fc : _cycle(fc, i) else cmin, cmax = get_clims(series[:subplot]) grad = isa(fc, ColorGradient) ? fc : cgrad() - if fz != nothing - grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)] - elseif lz != nothing - grad[clamp((_cycle(lz, i) - cmin) / (cmax - cmin), 0, 1)] - end + grad[clamp((_cycle(fz, i) - cmin) / (cmax - cmin), 0, 1)] end end From 8abd70bed8e4be9a92d2b7354448c4aa886ed17d Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Sun, 8 Apr 2018 20:59:21 +0100 Subject: [PATCH 644/720] =?UTF-8?q?Replace=20`=C3=97`=20with=20`\times`=20?= =?UTF-8?q?for=20PGFPlots.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 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 2396000e..dfde2a0d 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -425,8 +425,10 @@ function pgf_axis(sp::Subplot, letter) push!(style, string(letter, "ticklabels = {\$", join(tick_labels,"\$,\$"), "\$}")) elseif axis[:showaxis] tick_labels = ispolar(sp) && letter == :x ? [ticks[2][3:end]..., "0", "45"] : ticks[2] - tick_labels = ( axis[:formatter] in (:scientific, :auto) ? - string.("\$", convert_sci_unicode.(tick_labels), "\$") : tick_labels ) + if axis[:formatter] in (:scientific, :auto) + tick_labels = string.("\$", convert_sci_unicode.(tick_labels), "\$") + tick_labels = replace.(tick_labels, "×", "\\times") + end push!(style, string(letter, "ticklabels = {", join(tick_labels,","), "}")) else push!(style, string(letter, "ticklabels = {}")) @@ -598,7 +600,6 @@ end function _display(plt::Plot{PGFPlotsBackend}) # prepare the object - PGFPlots.pushPGFPlotsPreamble("\\usepackage{fontspec}") pgfplt = PGFPlots.plot(plt.o) # save an svg From b009da4b47d3ac5032506949ab7354a3853b672c Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Mon, 9 Apr 2018 21:20:41 +0100 Subject: [PATCH 645/720] Fix :native DateTime and categorical ticks for Plotly. --- src/backends/plotly.jl | 59 ++++++++++++++++++++++++++++++++++-------- src/utils.jl | 6 ++++- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8578b32e..ed29279d 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -485,6 +485,21 @@ function plotly_close_shapes(x, y) nanvcat(xs), nanvcat(ys) end +function plotly_data(series::Series, letter::Symbol, data) + axis = series[:subplot][Symbol(letter, :axis)] + + data = if axis[:ticks] == :native && data != nothing + plotly_native_data(axis, data) + else + data + end + + if series[:seriestype] in (:heatmap, :contour, :surface, :wireframe) + plotly_surface_data(series, data) + else + plotly_data(data) + end +end plotly_data(v) = v != nothing ? collect(v) : v plotly_data(surf::Surface) = surf.surf plotly_data(v::AbstractArray{R}) where {R<:Rational} = float(v) @@ -493,6 +508,28 @@ plotly_surface_data(series::Series, a::AbstractVector) = a plotly_surface_data(series::Series, a::AbstractMatrix) = transpose_z(series, a, false) plotly_surface_data(series::Series, a::Surface) = plotly_surface_data(series, a.surf) +function plotly_native_data(axis::Axis, data::AbstractArray) + if !isempty(axis[:discrete_values]) + construct_categorical_data(data, axis) + elseif axis[:formatter] in (datetimeformatter, dateformatter, timeformatter) + plotly_convert_to_datetime(data, axis[:formatter]) + else + data + end +end +plotly_native_data(axis::Axis, a::Surface) = Surface(plotly_native_data(axis, a.surf)) + +function plotly_convert_to_datetime(x::AbstractArray, formatter::Function) + if formatter == datetimeformatter + map(xi -> replace(formatter(xi), "T", " "), x) + elseif formatter == dateformatter + map(xi -> string(formatter(xi), " 00:00:00"), x) + elseif formatter == timeformatter + map(xi -> string(Dates.Date(Dates.now()), " ", formatter(xi)), x) + else + error("Invalid DateTime formatter. Expected Plots.datetime/date/time formatter but got $formatter") + end +end #ensures that a gradient is called if a single color is supplied where a gradient is needed (e.g. if a series recipe defines marker_z) as_gradient(grad::ColorGradient, α) = grad as_gradient(grad, α) = cgrad(alpha = α) @@ -513,20 +550,17 @@ function plotly_series(plt::Plot, series::Series) d_out[:yaxis] = "y$(y_idx)" d_out[:showlegend] = should_add_to_legend(series) - - x, y, z = map(letter -> (axis = sp[Symbol(letter, :axis)]; - if axis[:ticks] == :native && !isempty(axis[:discrete_values]) - axis[:discrete_values] - elseif st in (:heatmap, :contour, :surface, :wireframe) - plotly_surface_data(series, series[letter]) - else - plotly_data(series[letter]) - end), (:x, :y, :z)) - if st == :straightline x, y = straightline_data(series) + z = series[:z] + else + x, y, z = series[:x], series[:y], series[:z] end + x, y, z = (plotly_data(series, letter, data) + for (letter, data) in zip((:x, :y, :z), (x, y, z)) + ) + d_out[:name] = series[:label] isscatter = st in (:scatter, :scatter3d, :scattergl) @@ -643,7 +677,10 @@ function plotly_series_shapes(plt::Plot, series::Series) base_d[:name] = series[:label] # base_d[:legendgroup] = series[:label] - x, y = shape_data(series) + x, y = (plotly_data(series, letter, data) + for (letter, data) in zip((:x, :y), shape_data(series)) + ) + for (i,rng) in enumerate(segments) length(rng) < 2 && continue diff --git a/src/utils.jl b/src/utils.jl index 80d5487f..849c048e 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -207,7 +207,7 @@ function iter_segments(series::Series) end # helpers to figure out if there are NaN values in a list of array types -anynan(i::Int, args::Tuple) = any(a -> !isfinite(_cycle(a,i)), args) +anynan(i::Int, args::Tuple) = any(a -> try isnan(_cycle(a,i)) catch MethodError false end, args) anynan(istart::Int, iend::Int, args::Tuple) = any(i -> anynan(i, args), istart:iend) allnan(istart::Int, iend::Int, args::Tuple) = all(i -> anynan(i, args), istart:iend) @@ -1193,3 +1193,7 @@ function shape_data(series) end return x, y end + +function construct_categorical_data(x::AbstractArray, axis::Axis) + map(xi -> axis[:discrete_values][searchsortedfirst(axis[:continuous_values], xi)], x) +end From aeaa0c5f8d74cb709d682114230bd9d9e227e40f Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Mon, 9 Apr 2018 21:28:45 +0100 Subject: [PATCH 646/720] Fix axis limits for ticks = :native --- src/backends/plotly.jl | 5 ++++- src/backends/pyplot.jl | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index ed29279d..7fb94e41 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -264,7 +264,10 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) ax[:tickangle] = -axis[:rotation] lims = axis_limits(axis) - axis[:ticks] != :native ? ax[:range] = map(scalefunc(axis[:scale]), lims) : nothing + + if axis[:ticks] != :native || axis[:lims] != :auto + ax[:range] = map(scalefunc(axis[:scale]), lims) + end if !(axis[:ticks] in (nothing, :none, false)) ax[:titlefont] = plotly_font(guidefont(axis)) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cdf63b46..38d9f15f 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1077,7 +1077,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) pyaxis[Symbol(:tick_, pos)]() # the tick labels end py_set_scale(ax, axis) - axis[:ticks] != :native ? py_set_lims(ax, axis) : nothing + axis[:ticks] != :native || axis[:lims] != :auto ? py_set_lims(ax, axis) : nothing if ispolar(sp) && letter == :y ax[:set_rlabel_position](90) end From af60d03060722772512d190ef2a7ad142d92a841 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 13 Apr 2018 16:14:03 +0200 Subject: [PATCH 647/720] make alternative plots_heatmap seriestype --- src/Plots.jl | 1 + src/recipes.jl | 6 +++--- src/series.jl | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Plots.jl b/src/Plots.jl index f1026810..aec4ef17 100644 --- a/src/Plots.jl +++ b/src/Plots.jl @@ -183,6 +183,7 @@ include("output.jl") @shorthands histogram2d @shorthands density @shorthands heatmap +@shorthands plots_heatmap @shorthands hexbin @shorthands sticks @shorthands hline diff --git a/src/recipes.jl b/src/recipes.jl index 611c8407..7b389d29 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -390,8 +390,8 @@ end @deps bar shape # --------------------------------------------------------------------------- -# Heatmap -@recipe function f(::Type{Val{:heatmapr}}, x, y, z) +# Plots Heatmap +@recipe function f(::Type{Val{:plots_heatmap}}, x, y, z) xe, ye = heatmap_edges(x), heatmap_edges(y) m, n = size(z.surf) x_pts, y_pts = fill(NaN, 6 * m * n), fill(NaN, 6 * m * n) @@ -415,7 +415,7 @@ end label := "" () end -@deps heatmapr shape +@deps plots_heatmap shape # --------------------------------------------------------------------------- # Histograms diff --git a/src/series.jl b/src/series.jl index 4c8607fd..8b3f19bb 100644 --- a/src/series.jl +++ b/src/series.jl @@ -8,7 +8,7 @@ const FuncOrFuncs{F} = Union{F, Vector{F}, Matrix{F}} -all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :heatmapr), get(d, :seriestype, :none)) +all3D(d::KW) = trueOrAllTrue(st -> st in (:contour, :contourf, :heatmap, :surface, :wireframe, :contour3d, :image, :plots_heatmap), get(d, :seriestype, :none)) # unknown convertToAnyVector(x, d::KW) = error("No user recipe defined for $(typeof(x))") From 14b644777d962e7f15c38d6ecb1585bc73abb52a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 13 Apr 2018 16:21:18 +0200 Subject: [PATCH 648/720] add minimal version for GR dependency --- REQUIRE | 2 +- test/REQUIRE | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/REQUIRE b/REQUIRE index f0c12af5..c256c0a6 100644 --- a/REQUIRE +++ b/REQUIRE @@ -13,4 +13,4 @@ JSON NaNMath Requires Contour -GR +GR 0.31.0 diff --git a/test/REQUIRE b/test/REQUIRE index e748b0c5..09681156 100644 --- a/test/REQUIRE +++ b/test/REQUIRE @@ -2,7 +2,7 @@ StatPlots Images ImageMagick @osx QuartzImageIO -GR +GR 0.31.0 RDatasets VisualRegressionTests UnicodePlots From 506d3611fdead5c26996b478395e7c913becd12f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 13 Apr 2018 16:33:38 +0200 Subject: [PATCH 649/720] prepare release --- NEWS.md | 12 ++++++++++++ test/imgcomp.jl | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 265d53fd..14f5bad3 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,18 @@ --- ## (current master) +## 0.17.0 +- Add GR dependency to make it the default backend +- Improve histogram2d bin estimation +- Allow vector arguments for certain series attributes and support line_z and fill_z on GR, PyPlot, Plotly(JS) and PGFPlots +- Automatic scientific notation for tick labels +- Allow to set the theme in PLOTS_DEFAULTS +- Implement plots_heatmap seriestype providing a Plots recipe for heatmaps + +## 0.16.0 +- fix 3D plotting in PyPlot +- Infinite objects + ## 0.15.1 - fix scientific notation for labels in GR diff --git a/test/imgcomp.jl b/test/imgcomp.jl index d26d1635..1fa2aef9 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.16.0" +const _current_plots_version = v"0.17.0" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 4797f18819941e33f3bf51b9e9a6b9d2004464d2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Apr 2018 15:44:37 +0200 Subject: [PATCH 650/720] fix view for contours --- src/backends/pgfplots.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index dfde2a0d..f3386bad 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -509,7 +509,9 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:legendPos] = _pgfplots_legend_pos[legpos] end - if is3d(sp) + if any(s[:seriestype] == :contour for s in series_list(sp)) + kw[:view] = "{0}{90}" + elseif is3d(sp) azim, elev = sp[:camera] kw[:view] = "{$(azim)}{$(elev)}" end From f59ad1620ad84b3cb983b5285aa373fb7d80f1e0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 18 Apr 2018 16:13:28 +0200 Subject: [PATCH 651/720] contour improvements: colorbar, contour_labels and levels --- 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 f3386bad..5493cfd3 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -27,7 +27,7 @@ const _pgfplots_attr = merge_with_base_supported([ :tickfont, :guidefont, :legendfont, :grid, :legend, :colorbar, - :fill_z, :line_z, :marker_z, #:levels, + :fill_z, :line_z, :marker_z, :levels, # :ribbon, :quiver, :arrow, # :orientation, # :overwrite_figure, @@ -38,6 +38,7 @@ const _pgfplots_attr = merge_with_base_supported([ :tick_direction, :framestyle, :camera, + :contour_labels, ]) const _pgfplots_seriestype = [:path, :path3d, :scatter, :steppre, :stepmid, :steppost, :histogram2d, :ysticks, :xsticks, :contour, :shape, :straightline,] const _pgfplots_style = [:auto, :solid, :dash, :dot, :dashdot, :dashdotdot] @@ -250,6 +251,8 @@ function pgf_series(sp::Subplot, series::Series) func = if st == :histogram2d PGFPlots.Histogram2 else + kw[:labels] = series[:contour_labels] + kw[:levels] = series[:levels] PGFPlots.Contour end push!(series_collection, func(args...; kw...)) @@ -511,6 +514,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) if any(s[:seriestype] == :contour for s in series_list(sp)) kw[:view] = "{0}{90}" + kw[:colorbar] = !(sp[:colorbar] in (:none, :off, :hide, false)) elseif is3d(sp) azim, elev = sp[:camera] kw[:view] = "{$(azim)}{$(elev)}" From 73490903a3000d1d8e834284e7c5501e141502bd Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 25 Apr 2018 14:14:20 +0200 Subject: [PATCH 652/720] fix markerstrokecolor = :auto --- src/args.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/args.jl b/src/args.jl index 6616dc1c..9bfed7cb 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1529,6 +1529,8 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) # update markerstrokecolor d[:markerstrokecolor] = if d[:markerstrokecolor] == :match plot_color(sp[:foreground_color_subplot], d[:markerstrokealpha]) + elseif d[:markerstrokecolor] == :auto + getSeriesRGBColor(plot_color(d[:markercolor], d[:markeralpha]), sp, plotIndex) else getSeriesRGBColor(plot_color(d[:markerstrokecolor], d[:markerstrokealpha]), sp, plotIndex) end From fd37a9c660252361cd9396edbe7639ea5500836b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 27 Apr 2018 17:44:20 +0200 Subject: [PATCH 653/720] replace Int64 by Int --- src/series.jl | 2 +- src/utils.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/series.jl b/src/series.jl index 8b3f19bb..9af76774 100644 --- a/src/series.jl +++ b/src/series.jl @@ -627,7 +627,7 @@ group_as_matrix(t) = false else g = args[1] if length(g.args) == 1 - x = zeros(Int64, lengthGroup) + x = zeros(Int, lengthGroup) for indexes in groupby.groupIds x[indexes] = 1:length(indexes) end diff --git a/src/utils.jl b/src/utils.jl index b9ab6705..4fdaeb2c 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -197,7 +197,7 @@ function iter_segments(series::Series) if has_attribute_segments(series) return [i:(i + 1) for i in 1:(length(y) - 1)] else - segs = UnitRange{Int64}[] + segs = UnitRange{Int}[] args = is3d(series) ? (x, y, z) : (x, y) for seg in iter_segments(args...) push!(segs, seg) From bc638ea06ecdb9eb38cc713f130d1250433619c0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 9 Apr 2018 19:13:33 +0200 Subject: [PATCH 654/720] first gr tests --- src/args.jl | 2 +- src/backends/gr.jl | 16 +++++----------- src/utils.jl | 25 +++++++++++++++++++++++++ 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/args.jl b/src/args.jl index 9bfed7cb..ebd2c2f7 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1532,7 +1532,7 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) elseif d[:markerstrokecolor] == :auto getSeriesRGBColor(plot_color(d[:markercolor], d[:markeralpha]), sp, plotIndex) else - getSeriesRGBColor(plot_color(d[:markerstrokecolor], d[:markerstrokealpha]), sp, plotIndex) + getSeriesRGBColor.(d[:markerstrokecolor], sp, plotIndex) end # if marker_z, fill_z or line_z are set, ensure we have a gradient diff --git a/src/backends/gr.jl b/src/backends/gr.jl index b742eb15..76fd32b8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -357,21 +357,15 @@ function gr_draw_markers(series::Series, x, y, msize, mz) # draw a filled in shape, slightly bigger, to estimate a stroke if series[:markerstrokewidth] > 0 - cfunc(_cycle(series[:markerstrokecolor], i)) #, series[:markerstrokealpha]) + cfunc(get_markerstrokecolor(series, i)) + gr_set_transparency(get_markerstrokealpha(series, i)) gr_draw_marker(x[i], y[i], msi + series[:markerstrokewidth], shape) end - # draw the shape - if mz == nothing - cfunc(_cycle(series[:markercolor], i)) #, series[:markeralpha]) - else - # pick a color from the pre-loaded gradient - ci = round(Int, 1000 + _cycle(mz, i) * 255) - cfuncind(ci) - gr_set_transparency(_gr_gradient_alpha[ci-999]) - end - # don't draw filled area if marker shape is 1D + # draw the shape - don't draw filled area if marker shape is 1D if !(shape in (:hline, :vline, :+, :x)) + cfunc(get_markercolor(series, i)) + gr_set_transparency(get_markeralpha(series, i)) gr_draw_marker(x[i], y[i], msi, shape) end end diff --git a/src/utils.jl b/src/utils.jl index 6153f4b4..08c85797 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -656,6 +656,31 @@ function get_fillalpha(series, i::Int = 1) _cycle(series[:fillalpha], i) end +function get_markercolor(series, i::Int = 1) + mc = series[:markercolor] + mz = series[:marker_z] + if mz == nothing + isa(mc, ColorGradient) ? mc : _cycle(mc, i) + else + cmin, cmax = get_clims(series[:subplot]) + grad = isa(mc, ColorGradient) ? mc : cgrad() + grad[clamp((_cycle(mz, i) - cmin) / (cmax - cmin), 0, 1)] + end +end + +function get_markeralpha(series, i::Int = 1) + _cycle(series[:markeralpha], i) +end + +function get_markerstrokecolor(series, i::Int = 1) + msc = series[:markerstrokecolor] + isa(msc, ColorGradient) ? msc : _cycle(msc, i) +end + +function get_markerstrokealpha(series, i::Int = 1) + _cycle(series[:markerstrokealpha], i) +end + function has_attribute_segments(series::Series) # we want to check if a series needs to be split into segments just because # of its attributes From 1fd7c6e2f19b0de3eb382b7fd1ed9df60bffb8fa Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 01:10:07 +0200 Subject: [PATCH 655/720] fix args.jl --- src/args.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/args.jl b/src/args.jl index ebd2c2f7..be105f70 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1528,9 +1528,9 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) # update markerstrokecolor d[:markerstrokecolor] = if d[:markerstrokecolor] == :match - plot_color(sp[:foreground_color_subplot], d[:markerstrokealpha]) + plot_color(sp[:foreground_color_subplot]) elseif d[:markerstrokecolor] == :auto - getSeriesRGBColor(plot_color(d[:markercolor], d[:markeralpha]), sp, plotIndex) + getSeriesRGBColor.(d[:markercolor], sp, plotIndex) else getSeriesRGBColor.(d[:markerstrokecolor], sp, plotIndex) end From e8734daa4d4457d93ca6d5073dc98cf52676dcf7 Mon Sep 17 00:00:00 2001 From: Christoph Finkensiep Date: Sat, 5 May 2018 12:27:16 +0200 Subject: [PATCH 656/720] add legendgroups to shapes/segments and remove gaps in legend --- src/backends/plotly.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index f1daf3d7..0e6addbe 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -388,6 +388,7 @@ function plotly_layout(plt::Plot) :bgcolor => rgba_string(sp[:background_color_legend]), :bordercolor => rgba_string(sp[:foreground_color_legend]), :font => plotly_font(legendfont(sp)), + :tracegroupgap => 0, :x => xpos, :y => ypos ) @@ -678,7 +679,7 @@ function plotly_series_shapes(plt::Plot, series::Series) base_d[:xaxis] = "x$(x_idx)" base_d[:yaxis] = "y$(y_idx)" base_d[:name] = series[:label] - # base_d[:legendgroup] = series[:label] + base_d[:legendgroup] = series[:label] x, y = (plotly_data(series, letter, data) for (letter, data) in zip((:x, :y), shape_data(series)) @@ -733,6 +734,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) d_out = deepcopy(d_base) d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false + d_out[:legendgroup] = series[:label] # set the type if st in (:path, :scatter, :scattergl, :straightline) From 517c2f456c9d61e5e4f2a664fe4349633f6365d6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 16:22:41 +0200 Subject: [PATCH 657/720] markercolors for pyplot --- src/backends/pyplot.jl | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 38d9f15f..04290da1 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -570,12 +570,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if series[:markershape] != :none && st in (:path, :scatter, :path3d, :scatter3d, :steppre, :steppost, :bar) - if series[:marker_z] == nothing - extrakw[:c] = series[:markershape] in (:+, :x, :hline, :vline) ? py_markerstrokecolor(series) : py_color_fix(py_markercolor(series), x) + markercolor = if any(typeof(series[arg]) <: AVec for arg in (:markercolor, :markeralpha)) || series[:marker_z] != nothing + py_color(plot_color.(get_markercolor.(series, eachindex(x)), get_markeralpha.(series, eachindex(x)))) else - extrakw[:c] = convert(Vector{Float64}, series[:marker_z]) - extrakw[:cmap] = py_markercolormap(series) + py_color(plot_color(series[:markercolor], series[:markeralpha])) end + extrakw[:c] = py_color_fix(markercolor, x) xyargs = if st == :bar && !isvertical(series) (y, x) else @@ -591,11 +591,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) msc = py_markerstrokecolor(series) lw = py_dpi_scale(plt, series[:markerstrokewidth]) for i=1:length(y) - extrakw[:c] = if series[:marker_z] == nothing - py_color_fix(py_color(_cycle(series[:markercolor],i)), x) - else - extrakw[:c] - end + extrakw[:c] = _cycle(markercolor, i) push!(handle, ax[:scatter](_cycle(x,i), _cycle(y,i); label = series[:label], @@ -1014,10 +1010,16 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) kw[:ticks] = locator kw[:format] = formatter kw[:boundaries] = vcat(0, kw[:values] + 0.5) - elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z)) + elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z, :marker_z)) cmin, cmax = get_clims(sp) norm = pycolors[:Normalize](vmin = cmin, vmax = cmax) - f = colorbar_series[:line_z] != nothing ? py_linecolormap : py_fillcolormap + f = if colorbar_series[:line_z] != nothing + py_linecolormap + elseif colorbar_series[:fill_z] != nothing + py_fillcolormap + else + py_markercolormap + end cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series)) cmap[:set_array]([]) handle = cmap @@ -1077,7 +1079,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) pyaxis[Symbol(:tick_, pos)]() # the tick labels end py_set_scale(ax, axis) - axis[:ticks] != :native || axis[:lims] != :auto ? py_set_lims(ax, axis) : nothing + axis[:ticks] != :native ? py_set_lims(ax, axis) : nothing if ispolar(sp) && letter == :y ax[:set_rlabel_position](90) end From ee18a9dd6c3e2b850d7a6e9b2c04790d6448cdd3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 16:47:32 +0200 Subject: [PATCH 658/720] plotly markercolors --- src/backends/plotly.jl | 52 ++++++++++++------------------------------ 1 file changed, 14 insertions(+), 38 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index f1daf3d7..81bbbb82 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -265,7 +265,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) ax[:tickangle] = -axis[:rotation] lims = axis_limits(axis) - if axis[:ticks] != :native || axis[:lims] != :auto + if axis[:ticks] != :native || axis[:lims] != :auto ax[:range] = map(scalefunc(axis[:scale]), lims) end @@ -490,7 +490,7 @@ end function plotly_data(series::Series, letter::Symbol, data) axis = series[:subplot][Symbol(letter, :axis)] - + data = if axis[:ticks] == :native && data != nothing plotly_native_data(axis, data) else @@ -516,7 +516,7 @@ function plotly_native_data(axis::Axis, data::AbstractArray) construct_categorical_data(data, axis) elseif axis[:formatter] in (datetimeformatter, dateformatter, timeformatter) plotly_convert_to_datetime(data, axis[:formatter]) - else + else data end end @@ -632,31 +632,17 @@ function plotly_series(plt::Plot, series::Series) # add "marker" if hasmarker + inds = eachindex(x) d_out[:marker] = KW( :symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])), # :opacity => series[:markeralpha], :size => 2 * series[:markersize], - # :color => rgba_string(series[:markercolor]), + :color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))), :line => KW( - :color => _cycle(rgba_string.(series[:markerstrokecolor]),eachindex(series[:x])), + :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))), :width => series[:markerstrokewidth], ), ) - - # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient - if series[:marker_z] == nothing - d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]),eachindex(series[:x])) - else - # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) - # grad = as_gradient(series[:markercolor], series[:markeralpha]) - cmin, cmax = get_clims(sp) - # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) - d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in series[:marker_z]] - d_out[:marker][:cmin] = cmin - d_out[:marker][:cmax] = cmax - d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha]) - d_out[:marker][:showscale] = hascolorbar(sp) - end end plotly_polar!(d_out, series) @@ -680,7 +666,7 @@ function plotly_series_shapes(plt::Plot, series::Series) base_d[:name] = series[:label] # base_d[:legendgroup] = series[:label] - x, y = (plotly_data(series, letter, data) + x, y = (plotly_data(series, letter, data) for (letter, data) in zip((:x, :y), shape_data(series)) ) @@ -712,6 +698,8 @@ function plotly_series_shapes(plt::Plot, series::Series) push!(d_outs, plotly_colorbar_hack(series, base_d, :fill)) elseif series[:line_z] != nothing push!(d_outs, plotly_colorbar_hack(series, base_d, :line)) + elseif series[:marker_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, base_d, :marker)) end d_outs end @@ -765,31 +753,17 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) # add "marker" if hasmarker + inds = eachindex(x) d_out[:marker] = KW( :symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])), # :opacity => series[:markeralpha], :size => 2 * series[:markersize], - # :color => rgba_string(series[:markercolor]), + :color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))), :line => KW( - :color => _cycle(rgba_string.(series[:markerstrokecolor]), eachindex(rng)), + :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))), :width => series[:markerstrokewidth], ), ) - - # gotta hack this (for now?) since plotly can't handle rgba values inside the gradient - if series[:marker_z] == nothing - d_out[:marker][:color] = _cycle(rgba_string.(series[:markercolor]), eachindex(rng)) - else - # grad = ColorGradient(series[:markercolor], alpha=series[:markeralpha]) - # grad = as_gradient(series[:markercolor], series[:markeralpha]) - cmin, cmax = get_clims(sp) - # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) - d_out[:marker][:color] = [clamp(zi, cmin, cmax) for zi in _cycle(series[:marker_z], rng)] - d_out[:marker][:cmin] = cmin - d_out[:marker][:cmax] = cmax - d_out[:marker][:colorscale] = plotly_colorscale(series[:markercolor], series[:markeralpha]) - d_out[:marker][:showscale] = hascolorbar(sp) - end end # add "line" @@ -848,6 +822,8 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) push!(d_outs, plotly_colorbar_hack(series, d_base, :line)) elseif series[:fill_z] != nothing push!(d_outs, plotly_colorbar_hack(series, d_base, :fill)) + elseif series[:marker_z] != nothing + push!(d_outs, plotly_colorbar_hack(series, d_base, :marker)) end d_outs From ba9a8d52cc32ae7a7e6e8ffb98dab7053cb5b7bf Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 17:44:13 +0200 Subject: [PATCH 659/720] pgfplots markercolors --- src/backends/pgfplots.jl | 7 ++----- src/utils.jl | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 5493cfd3..e07daa5d 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -173,11 +173,8 @@ end function pgf_marker(d, i = 1) shape = _cycle(d[:markershape], i) - cstr, a = pgf_color(_cycle(d[:markercolor], i)) - if d[:markeralpha] != nothing - a = _cycle(d[:markeralpha], i) - end - cstr_stroke, a_stroke = pgf_color(_cycle(d[:markerstrokecolor], i)) + cstr, a = pgf_color(plot_color(get_markercolor(d, i), get_markeralpha(d, i))) + cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(d, i), get_markerstrokealpha(d, i))) if d[:markerstrokealpha] != nothing a_stroke = _cycle(d[:markerstrokealpha], i) end diff --git a/src/utils.jl b/src/utils.jl index 08c85797..d6c217c0 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -691,7 +691,7 @@ function has_attribute_segments(series::Series) end series[:seriestype] == :shape && return false # ... else we check relevant attributes if they have multiple inputs - return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z)) + return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha, :markercolor, :markeralpha, :markerstrokecolor, :markerstrokealpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z, :marker_z)) end # --------------------------------------------------------------- From 5797ad2d5ba587bf364e0a87e414668052a5be7b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 18:37:16 +0200 Subject: [PATCH 660/720] fix plotly --- src/backends/plotly.jl | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 81bbbb82..aefc4eab 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -580,9 +580,19 @@ function plotly_series(plt::Plot, series::Series) end # set the "type" - if st in (:path, :scatter, :scattergl, :straightline, :path3d, :scatter3d) + if st in (:path, :straightline, :path3d) return plotly_series_segments(series, d_out, x, y, z) + elseif st in (:scatter, :scattergl) + d_out[:type] = string(st) + d_out[:mode] = hasline ? "lines+markers" : "markers" + d_out[:x], d_out[:y] = x, y + + elseif st == :scatter3d + d_out[:mode] = string(st) + d_out[:mode] = hasline ? "lines+markers" : "markers" + d_out[:x], d_out[:y], d_out[:z] = x, y, z + elseif st == :heatmap d_out[:type] = "heatmap" d_out[:x], d_out[:y], d_out[:z] = x, y, z @@ -753,15 +763,14 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) # add "marker" if hasmarker - inds = eachindex(x) d_out[:marker] = KW( - :symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])), + :symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))), # :opacity => series[:markeralpha], - :size => 2 * series[:markersize], - :color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))), + :size => 2 * _cycle(series[:markersize], i), + :color => rgba_string.(plot_color.(get_markercolor.(series, i), get_markeralpha.(series, i))), :line => KW( - :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))), - :width => series[:markerstrokewidth], + :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, i), get_markerstrokealpha.(series, i))), + :width => _cycle(series[:markerstrokewidth], i), ), ) end From 048636e8942bf1ce27a6b74658d922d6e0d9cbe6 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 18:50:57 +0200 Subject: [PATCH 661/720] fix plotly marker_z colorbar --- src/backends/plotly.jl | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index aefc4eab..d4942df5 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -658,7 +658,17 @@ function plotly_series(plt::Plot, series::Series) plotly_polar!(d_out, series) plotly_hover!(d_out, series[:hover]) - return [d_out] + d_outs = [d_out] + if series[:marker_z] != nothing + d_base = KW( + :xaxis => "x$(x_idx)", + :yaxis => "y$(y_idx)", + :name => series[:label], + ) + push!(d_outs, plotly_colorbar_hack(series, d_base, :marker)) + end + + return d_outs end function plotly_series_shapes(plt::Plot, series::Series) @@ -670,11 +680,12 @@ function plotly_series_shapes(plt::Plot, series::Series) # these are the axes that the series should be mapped to x_idx, y_idx = plotly_link_indicies(plt, series[:subplot]) - base_d = KW() - base_d[:xaxis] = "x$(x_idx)" - base_d[:yaxis] = "y$(y_idx)" - base_d[:name] = series[:label] - # base_d[:legendgroup] = series[:label] + d_base = KW( + :xaxis => "x$(x_idx)", + :yaxis => "y$(y_idx)", + :name => series[:label], + ) + # d_base[:legendgroup] = series[:label] x, y = (plotly_data(series, letter, data) for (letter, data) in zip((:x, :y), shape_data(series)) @@ -684,7 +695,7 @@ function plotly_series_shapes(plt::Plot, series::Series) length(rng) < 2 && continue # to draw polygons, we actually draw lines with fill - d_out = merge(base_d, KW( + d_out = merge(d_base, KW( :type => "scatter", :mode => "lines", :x => vcat(x[rng], x[rng[1]]), @@ -705,11 +716,11 @@ function plotly_series_shapes(plt::Plot, series::Series) d_outs[i] = d_out end if series[:fill_z] != nothing - push!(d_outs, plotly_colorbar_hack(series, base_d, :fill)) + push!(d_outs, plotly_colorbar_hack(series, d_base, :fill)) elseif series[:line_z] != nothing - push!(d_outs, plotly_colorbar_hack(series, base_d, :line)) + push!(d_outs, plotly_colorbar_hack(series, d_base, :line)) elseif series[:marker_z] != nothing - push!(d_outs, plotly_colorbar_hack(series, base_d, :marker)) + push!(d_outs, plotly_colorbar_hack(series, d_base, :marker)) end d_outs end From 4ee5539e3dc240019604951abebb9c7560f4b305 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 19:22:34 +0200 Subject: [PATCH 662/720] plotly fixes --- src/backends/plotly.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index d4942df5..3f4b610d 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -646,11 +646,11 @@ function plotly_series(plt::Plot, series::Series) d_out[:marker] = KW( :symbol => get(_plotly_markers, series[:markershape], string(series[:markershape])), # :opacity => series[:markeralpha], - :size => 2 * series[:markersize], + :size => 2 * _cycle(series[:markersize], inds), :color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))), :line => KW( :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))), - :width => series[:markerstrokewidth], + :width => _cycle(series[:markerstrokewidth], inds), ), ) end From 22f69a99e2cbd15d09af7577ad2a03bd4b6345be Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 20:42:47 +0200 Subject: [PATCH 663/720] remove cfuncind in gr_draw_markers --- src/backends/gr.jl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 76fd32b8..ad235940 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -353,7 +353,6 @@ function gr_draw_markers(series::Series, x, y, msize, mz) msi = _cycle(msize, i) shape = _cycle(shapes, i) cfunc = isa(shape, Shape) ? gr_set_fillcolor : gr_set_markercolor - cfuncind = isa(shape, Shape) ? GR.setfillcolorind : GR.setmarkercolorind # draw a filled in shape, slightly bigger, to estimate a stroke if series[:markerstrokewidth] > 0 @@ -1040,10 +1039,6 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if series[:markershape] != :none - if series[:marker_z] != nothing - zmin, zmax = extrema(series[:marker_z]) - GR.setspace(zmin, zmax, 0, 90) - end gr_draw_markers(series, x, y, clims) end From 34d9d042aa78ecf130c9622caa945381b8d3dd5f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 5 May 2018 21:42:08 +0200 Subject: [PATCH 664/720] update iter_segments for scatters --- src/backends/pgfplots.jl | 7 ------- src/backends/plotly.jl | 30 +++++------------------------- src/utils.jl | 6 +++++- 3 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index e07daa5d..19155c92 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -175,9 +175,6 @@ function pgf_marker(d, i = 1) shape = _cycle(d[:markershape], i) cstr, a = pgf_color(plot_color(get_markercolor(d, i), get_markeralpha(d, i))) cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(d, i), get_markerstrokealpha(d, i))) - if d[:markerstrokealpha] != nothing - a_stroke = _cycle(d[:markerstrokealpha], i) - end """ mark = $(get(_pgfplots_markers, shape, "*")), mark size = $(0.5 * _cycle(d[:markersize], i)), @@ -219,10 +216,6 @@ function pgf_series(sp::Subplot, series::Series) straightline_data(series) elseif st == :shape shape_data(series) - elseif d[:marker_z] != nothing - # If a marker_z is used pass it as third coordinate to a 2D plot. - # See "Scatter Plots" in PGFPlots documentation - d[:x], d[:y], d[:marker_z] elseif ispolar(sp) theta, r = filter_radial_data(d[:x], d[:y], axis_limits(sp[:yaxis])) rad2deg.(theta), r diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 3f4b610d..0e69bb17 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -580,19 +580,9 @@ function plotly_series(plt::Plot, series::Series) end # set the "type" - if st in (:path, :straightline, :path3d) + if st in (:path, :scatter, :scattergl, :straightline, :path3d, :scatter3d) return plotly_series_segments(series, d_out, x, y, z) - elseif st in (:scatter, :scattergl) - d_out[:type] = string(st) - d_out[:mode] = hasline ? "lines+markers" : "markers" - d_out[:x], d_out[:y] = x, y - - elseif st == :scatter3d - d_out[:mode] = string(st) - d_out[:mode] = hasline ? "lines+markers" : "markers" - d_out[:x], d_out[:y], d_out[:z] = x, y, z - elseif st == :heatmap d_out[:type] = "heatmap" d_out[:x], d_out[:y], d_out[:z] = x, y, z @@ -658,17 +648,7 @@ function plotly_series(plt::Plot, series::Series) plotly_polar!(d_out, series) plotly_hover!(d_out, series[:hover]) - d_outs = [d_out] - if series[:marker_z] != nothing - d_base = KW( - :xaxis => "x$(x_idx)", - :yaxis => "y$(y_idx)", - :name => series[:label], - ) - push!(d_outs, plotly_colorbar_hack(series, d_base, :marker)) - end - - return d_outs + return [d_out] end function plotly_series_shapes(plt::Plot, series::Series) @@ -738,7 +718,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) d_outs = Vector{KW}((hasfillrange ? 2 : 1 ) * length(segments)) for (i,rng) in enumerate(segments) - length(rng) < 2 && continue + !isscatter && length(rng) < 2 && continue d_out = deepcopy(d_base) d_out[:showlegend] = i==1 ? should_add_to_legend(series) : false @@ -778,9 +758,9 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) :symbol => get(_plotly_markers, _cycle(series[:markershape], i), string(_cycle(series[:markershape], i))), # :opacity => series[:markeralpha], :size => 2 * _cycle(series[:markersize], i), - :color => rgba_string.(plot_color.(get_markercolor.(series, i), get_markeralpha.(series, i))), + :color => rgba_string(plot_color(get_markercolor(series, i), get_markeralpha(series, i))), :line => KW( - :color => rgba_string.(plot_color.(get_markerstrokecolor.(series, i), get_markerstrokealpha.(series, i))), + :color => rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i))), :width => _cycle(series[:markerstrokewidth], i), ), ) diff --git a/src/utils.jl b/src/utils.jl index d6c217c0..8ee4a656 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -195,7 +195,11 @@ end function iter_segments(series::Series) x, y, z = series[:x], series[:y], series[:z] if has_attribute_segments(series) - return [i:(i + 1) for i in 1:(length(y) - 1)] + if series[:seriestype] in (:scatter, :scatter3d) + return [[i] for i in 1:length(y)] + else + return [i:(i + 1) for i in 1:(length(y) - 1)] + end else segs = UnitRange{Int64}[] args = is3d(series) ? (x, y, z) : (x, y) From a3e8af40b2dcb684cf52828b42598dfcfb9498f4 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 10 May 2018 22:21:50 +0200 Subject: [PATCH 665/720] make get_***color return plot_color --- src/utils.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/utils.jl b/src/utils.jl index 1bfc2651..9c085f50 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -624,7 +624,7 @@ function get_linecolor(series, i::Int = 1) lc = series[:linecolor] lz = series[:line_z] if lz == nothing - isa(lc, ColorGradient) ? lc : _cycle(lc, i) + isa(lc, ColorGradient) ? lc : plot_color(_cycle(lc, i)) else cmin, cmax = get_clims(series[:subplot]) grad = isa(lc, ColorGradient) ? lc : cgrad() @@ -648,7 +648,7 @@ function get_fillcolor(series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] if fz == nothing - isa(fc, ColorGradient) ? fc : _cycle(fc, i) + isa(fc, ColorGradient) ? fc : plot_color(_cycle(fc, i)) else cmin, cmax = get_clims(series[:subplot]) grad = isa(fc, ColorGradient) ? fc : cgrad() @@ -664,7 +664,7 @@ function get_markercolor(series, i::Int = 1) mc = series[:markercolor] mz = series[:marker_z] if mz == nothing - isa(mc, ColorGradient) ? mc : _cycle(mc, i) + isa(mc, ColorGradient) ? mc : plot_color(_cycle(mc, i)) else cmin, cmax = get_clims(series[:subplot]) grad = isa(mc, ColorGradient) ? mc : cgrad() From 1f3c4948c6d3411e3620a655b855e5054bd1f48e Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 11 May 2018 18:38:04 +0200 Subject: [PATCH 666/720] update series attributes after processing series recipes --- src/args.jl | 39 ++++++++++++++++++++++++--------------- src/pipeline.jl | 1 + 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/src/args.jl b/src/args.jl index be105f70..c9800eb6 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1473,26 +1473,19 @@ function _replace_linewidth(d::KW) end function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) - pkg = plt.backend - globalIndex = d[:series_plotindex] - # add default values to our dictionary, being careful not to delete what we just added! for (k,v) in _series_defaults slice_arg!(d, d, k, v, commandIndex, false) end - # this is how many series belong to this subplot - # plotIndex = count(series -> series.d[:subplot] === sp && series.d[:primary], plt.series_list) - plotIndex = 0 - for series in sp.series_list - if series[:primary] - plotIndex += 1 - end - end - # plotIndex = count(series -> series[:primary], sp.series_list) - if get(d, :primary, true) - plotIndex += 1 - end + return d +end + + +function _update_series_attributes!(d::KW, plt::Plot, sp::Subplot) + pkg = plt.backend + globalIndex = d[:series_plotindex] + plotIndex = _series_index(d, sp) aliasesAndAutopick(d, :linestyle, _styleAliases, supported_styles(pkg), plotIndex) aliasesAndAutopick(d, :markershape, _markerAliases, supported_markers(pkg), plotIndex) @@ -1562,3 +1555,19 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) _replace_linewidth(d) d end + +function _series_index(d, sp) + idx = 0 + for series in series_list(sp) + if series[:primary] + idx += 1 + end + if series == d + return idx + end + end + if get(d, :primary, true) + idx += 1 + end + return idx +end diff --git a/src/pipeline.jl b/src/pipeline.jl index 931aa76e..6921cb98 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -398,6 +398,7 @@ function _process_seriesrecipe(plt::Plot, d::KW) sp = _prepare_subplot(plt, d) _prepare_annotations(sp, d) _expand_subplot_extrema(sp, d, st) + _update_series_attributes!(d, plt, sp) _add_the_series(plt, sp, d) else From bd2756c0bf6aade388fe3a068c9a968803880f2d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 13 May 2018 19:48:49 +0200 Subject: [PATCH 667/720] fix ribbon for plotly --- src/backends/plotly.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 2fff6cb7..0e3be76b 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -807,8 +807,9 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) else # if fillrange is a tuple with upper and lower limit, d_out_fillrange # is the series that will do the filling + fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2) d_out_fillrange[:x], d_out_fillrange[:y] = - concatenate_fillrange(x[rng], series[:fillrange][rng]) + concatenate_fillrange(x[rng], fillrng) d_out_fillrange[:line][:width] = 0 delete!(d_out, :fill) delete!(d_out, :fillcolor) From 41e4c80494e6a9b3eb01846aea80b031dcefd162 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 13 May 2018 19:49:02 +0200 Subject: [PATCH 668/720] fix ribbon for plotly --- src/backends/plotly.jl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 0e3be76b..45ed7727 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -808,8 +808,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) # if fillrange is a tuple with upper and lower limit, d_out_fillrange # is the series that will do the filling fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2) - d_out_fillrange[:x], d_out_fillrange[:y] = - concatenate_fillrange(x[rng], fillrng) + d_out_fillrange[:x], d_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng) d_out_fillrange[:line][:width] = 0 delete!(d_out, :fill) delete!(d_out, :fillcolor) From 60b9cd8789102d4c2cd8502f2ead084e3dc10307 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 13 May 2018 19:52:26 +0200 Subject: [PATCH 669/720] remove space --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 45ed7727..30d0c05c 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -808,7 +808,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) # if fillrange is a tuple with upper and lower limit, d_out_fillrange # is the series that will do the filling fillrng = Tuple(series[:fillrange][i][rng] for i in 1:2) - d_out_fillrange[:x], d_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng) + d_out_fillrange[:x], d_out_fillrange[:y] = concatenate_fillrange(x[rng], fillrng) d_out_fillrange[:line][:width] = 0 delete!(d_out, :fill) delete!(d_out, :fillcolor) From f792aea98efa4fb593aa308fdbfdb95a1eccd782 Mon Sep 17 00:00:00 2001 From: Jeff Eldredge Date: Wed, 16 May 2018 11:19:10 -0700 Subject: [PATCH 670/720] Changed treatment of contour types, to allow for x,y in grid form, allowed by PyPlot backend --- src/backends/pyplot.jl | 6 ++++++ src/pipeline.jl | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index cdf63b46..7e5924c3 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -638,6 +638,12 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st in (:contour, :contour3d) z = transpose_z(series, z.surf) + if typeof(x)<:Plots.Surface + x = Plots.transpose_z(series, x.surf) + end + if typeof(y)<:Plots.Surface + y = Plots.transpose_z(series, y.surf) + end if st == :contour3d extrakw[:extend3d] = true diff --git a/src/pipeline.jl b/src/pipeline.jl index 931aa76e..66e8c7f1 100644 --- a/src/pipeline.jl +++ b/src/pipeline.jl @@ -327,7 +327,7 @@ end function _override_seriestype_check(d::KW, st::Symbol) # do we want to override the series type? - if !is3d(st) + if !is3d(st) && !(st in (:contour,:contour3d)) z = d[:z] if !isa(z, Void) && (size(d[:x]) == size(d[:y]) == size(z)) st = (st == :scatter ? :scatter3d : :path3d) From 8bc437a84e0854938c18b492508cb91829689811 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 21 May 2018 09:53:58 +0200 Subject: [PATCH 671/720] prepare release --- NEWS.md | 9 +++++++++ test/imgcomp.jl | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 14f5bad3..a39c748e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,15 @@ --- ## (current master) +## 0.17.1 +- Fix contour for PGFPlots +- 32Bit fix: Int64 -> Int +- Make series of shapes and segments toggle together in Plotly(JS) +- Fix marker arguments +- Fix processing order of series recipes +- Fix Plotly(JS) ribbon +- Contour plots with x,y in grid form on PyPlot + ## 0.17.0 - Add GR dependency to make it the default backend - Improve histogram2d bin estimation diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 1fa2aef9..d582e672 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.17.0" +const _current_plots_version = v"0.17.1" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 27e68ed6a97a02f59c74309e9a7a9b2f4099705b Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 21 May 2018 14:49:18 +0200 Subject: [PATCH 672/720] only try the pdf -> png convert if the backend support application/pdf mime --- src/output.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/output.jl b/src/output.jl index 3932d94b..ca1461c8 100644 --- a/src/output.jl +++ b/src/output.jl @@ -218,9 +218,10 @@ closeall() = closeall(backend()) # --------------------------------------------------------- # A backup, if no PNG generation is defined, is to try to make a PDF and use FileIO to convert +const PDFBackends = Union{PGFPlotsBackend,PlotlyJSBackend,PyPlotBackend,InspectDRBackend,GRBackend} if is_installed("FileIO") @eval import FileIO - function _show(io::IO, ::MIME"image/png", plt::Plot) + function _show(io::IO, ::MIME"image/png", plt::Plot{<:PDFBackends}) fn = tempname() # first save a pdf file From d02658e0ba6c20f4154a97ddd8bb76e28a98184f Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 21 May 2018 15:09:50 +0200 Subject: [PATCH 673/720] add text/plain default, fix #1515 --- src/backends/hdf5.jl | 4 ---- src/backends/inspectdr.jl | 1 - src/output.jl | 6 +++--- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/backends/hdf5.jl b/src/backends/hdf5.jl index 2cbe7a76..a82a277f 100644 --- a/src/backends/hdf5.jl +++ b/src/backends/hdf5.jl @@ -240,10 +240,6 @@ end # ---------------------------------------------------------------- -_show(io::IO, mime::MIME"text/plain", plt::Plot{HDF5Backend}) = nothing #Don't show - -# ---------------------------------------------------------------- - # Display/show the plot (open a GUI window, or browser page, for example). function _display(plt::Plot{HDF5Backend}) msg = "HDF5 interface does not support `display()` function." diff --git a/src/backends/inspectdr.jl b/src/backends/inspectdr.jl index d0d3e285..8cc2a22c 100644 --- a/src/backends/inspectdr.jl +++ b/src/backends/inspectdr.jl @@ -523,7 +523,6 @@ for (mime, fmt) in _inspectdr_mimeformats_nodpi _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 # ---------------------------------------------------------------- diff --git a/src/output.jl b/src/output.jl index 3932d94b..8cb2a05c 100644 --- a/src/output.jl +++ b/src/output.jl @@ -211,6 +211,9 @@ for mime in keys(_mimeformats) end end +# default text/plain for all backends +_show(io::IO, ::MIME{Symbol("text/plain")}, plt::Plot) = show(io, plt) + "Close all open gui windows of the current backend" closeall() = closeall(backend()) @@ -322,9 +325,6 @@ end if Juno.isactive() Media.media(Plot, Media.Plot) - - _show(io::IO, m::MIME"text/plain", plt::Plot{B}) where {B} = print(io, "Plot{$B}()") - function Juno.render(e::Juno.Editor, plt::Plot) Juno.render(e, nothing) end From 7ce96a4e3d3d1f512969f035fc199acfb5b67802 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 13:25:00 +0200 Subject: [PATCH 674/720] set fallback tick specification for axes with discrete values --- src/axes.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index db4137e3..4a9327f3 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -249,12 +249,12 @@ function get_ticks(axis::Axis) cv, dv = if !isempty(dvals) # discrete ticks... n = length(dvals) - rng = if ticks == :auto - Int[round(Int,i) for i in linspace(1, n, 15)] - elseif ticks == :all + rng = if ticks == :all 1:n elseif typeof(ticks) <: Int Int[round(Int,i) for i in linspace(1, n, ticks)] + else + Int[round(Int,i) for i in linspace(1, n, 15)] end axis[:continuous_values][rng], dvals[rng] elseif typeof(ticks) <: Symbol From 54158a034040e0de5a24ce19c51fde7e17031975 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 13:59:16 +0200 Subject: [PATCH 675/720] check for dvals at the end --- src/axes.jl | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index 4a9327f3..d9536c48 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -246,18 +246,7 @@ function get_ticks(axis::Axis) ticks = ticks == :native ? :auto : ticks dvals = axis[:discrete_values] - cv, dv = if !isempty(dvals) - # discrete ticks... - n = length(dvals) - rng = if ticks == :all - 1:n - elseif typeof(ticks) <: Int - Int[round(Int,i) for i in linspace(1, n, ticks)] - else - Int[round(Int,i) for i in linspace(1, n, 15)] - end - axis[:continuous_values][rng], dvals[rng] - elseif typeof(ticks) <: Symbol + cv, dv = if typeof(ticks) <: Symbol if ispolar(axis.sps[1]) && axis[:letter] == :x #force theta axis to be full circle (collect(0:pi/4:7pi/4), string.(0:45:315)) @@ -271,6 +260,17 @@ function get_ticks(axis::Axis) elseif typeof(ticks) <: NTuple{2, Any} # assuming we're passed (ticks, labels) ticks + elseif !isempty(dvals) + # discrete ticks... + n = length(dvals) + rng = if ticks == :auto + Int[round(Int,i) for i in linspace(1, n, 15)] + elseif ticks == :all + 1:n + elseif typeof(ticks) <: Int + Int[round(Int,i) for i in linspace(1, n, ticks)] + end + axis[:continuous_values][rng], dvals[rng] else error("Unknown ticks type in get_ticks: $(typeof(ticks))") end From 02ede8020fdbb1fef4021906bbbe686deb62cb2d Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 14:26:35 +0200 Subject: [PATCH 676/720] fix tick conditions --- src/axes.jl | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/src/axes.jl b/src/axes.jl index d9536c48..c873086e 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -247,7 +247,16 @@ function get_ticks(axis::Axis) dvals = axis[:discrete_values] cv, dv = if typeof(ticks) <: Symbol - if ispolar(axis.sps[1]) && axis[:letter] == :x + if !isempty(dvals) + # discrete ticks... + n = length(dvals) + rng = if ticks == :auto + Int[round(Int,i) for i in linspace(1, n, 15)] + else # if ticks == :all + 1:n + end + axis[:continuous_values][rng], dvals[rng] + elseif ispolar(axis.sps[1]) && axis[:letter] == :x #force theta axis to be full circle (collect(0:pi/4:7pi/4), string.(0:45:315)) else @@ -255,22 +264,16 @@ function get_ticks(axis::Axis) optimal_ticks_and_labels(axis) end elseif typeof(ticks) <: Union{AVec, Int} - # override ticks, but get the labels - optimal_ticks_and_labels(axis, ticks) + if !isempty(dvals) && typeof(ticks) <: Int + rng = Int[round(Int,i) for i in linspace(1, length(dvals), ticks)] + axis[:continuous_values][rng], dvals[rng] + else + # override ticks, but get the labels + optimal_ticks_and_labels(axis, ticks) + end elseif typeof(ticks) <: NTuple{2, Any} # assuming we're passed (ticks, labels) ticks - elseif !isempty(dvals) - # discrete ticks... - n = length(dvals) - rng = if ticks == :auto - Int[round(Int,i) for i in linspace(1, n, 15)] - elseif ticks == :all - 1:n - elseif typeof(ticks) <: Int - Int[round(Int,i) for i in linspace(1, n, ticks)] - end - axis[:continuous_values][rng], dvals[rng] else error("Unknown ticks type in get_ticks: $(typeof(ticks))") end From 17e8bc6949a8ca2015fdbdc4af4d8fa1387995cd Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 16:13:39 +0200 Subject: [PATCH 677/720] set legend alpha in pyplot --- src/backends/pyplot.jl | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 719496fe..19dfb72c 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1282,27 +1282,30 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # if anything was added, call ax.legend and set the colors if !isempty(handles) + fgcolor = py_color(sp[:foreground_color_legend]) leg = ax[:legend](handles, labels, loc = get(_pyplot_legend_pos, leg, "best"), scatterpoints = 1, - fontsize = py_dpi_scale(plt, sp[:legendfontsize]) - # family = sp[:legendfont].family - # framealpha = 0.6 + fontsize = py_dpi_scale(plt, sp[:legendfontsize]), + # family = sp[:legendfont].family, + # framealpha = 0.6, + facecolor = py_color(sp[:background_color_legend]), + edgecolor = py_color(sp[:foreground_color_legend]), + framealpha = alpha(sp[:background_color_legend]), ) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) - fgcolor = py_color(sp[:foreground_color_legend]) lfcolor = py_color(sp[:legendfontcolor]) for txt in leg[:get_texts]() PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily]) end # set some legend properties - frame = leg[:get_frame]() - frame[set_facecolor_sym](py_color(sp[:background_color_legend])) - frame[:set_edgecolor](fgcolor) + # frame = leg[:get_frame]() + # frame[set_facecolor_sym](py_color(sp[:background_color_legend])) + # frame[:set_edgecolor](fgcolor) end end end From 56cf5249f9778fa5b8fe08799f8a5c5e1922b94a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 16:18:56 +0200 Subject: [PATCH 678/720] remove extra line --- 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 19dfb72c..be3adbc7 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1282,7 +1282,6 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # if anything was added, call ax.legend and set the colors if !isempty(handles) - fgcolor = py_color(sp[:foreground_color_legend]) leg = ax[:legend](handles, labels, loc = get(_pyplot_legend_pos, leg, "best"), @@ -1297,6 +1296,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) + # fgcolor = py_color(sp[:foreground_color_legend]) lfcolor = py_color(sp[:legendfontcolor]) for txt in leg[:get_texts]() PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily]) From 4a55467eef2a6336e96ae716f987c54380e55e4f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 16:20:19 +0200 Subject: [PATCH 679/720] add plot_color --- 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 be3adbc7..d55b3f42 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1291,7 +1291,7 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # framealpha = 0.6, facecolor = py_color(sp[:background_color_legend]), edgecolor = py_color(sp[:foreground_color_legend]), - framealpha = alpha(sp[:background_color_legend]), + framealpha = alpha(plot_color(sp[:background_color_legend])), ) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) From bf518a961ecf77f4f8768ad4d78daab938f7a2ed Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 30 May 2018 16:28:56 +0200 Subject: [PATCH 680/720] clean up --- src/backends/pyplot.jl | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index d55b3f42..0110d086 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1287,8 +1287,6 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) loc = get(_pyplot_legend_pos, leg, "best"), scatterpoints = 1, fontsize = py_dpi_scale(plt, sp[:legendfontsize]), - # family = sp[:legendfont].family, - # framealpha = 0.6, facecolor = py_color(sp[:background_color_legend]), edgecolor = py_color(sp[:foreground_color_legend]), framealpha = alpha(plot_color(sp[:background_color_legend])), @@ -1296,16 +1294,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) - # fgcolor = py_color(sp[:foreground_color_legend]) - lfcolor = py_color(sp[:legendfontcolor]) for txt in leg[:get_texts]() - PyPlot.plt[:setp](txt, color = lfcolor, family = sp[:legendfontfamily]) + PyPlot.plt[:setp](txt, color = py_color(sp[:legendfontcolor]), family = sp[:legendfontfamily]) end - - # set some legend properties - # frame = leg[:get_frame]() - # frame[set_facecolor_sym](py_color(sp[:background_color_legend])) - # frame[:set_edgecolor](fgcolor) end end end From 2d280edf0c878f3f52a13d113eccabdc1fa0680a Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 4 Jun 2018 10:13:53 +0200 Subject: [PATCH 681/720] forward showable call to _show instead of show since all backends return true otherwise --- src/backends/plotly.jl | 9 --------- src/output.jl | 7 ++++--- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 30d0c05c..64c9f21d 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -922,15 +922,6 @@ end # ---------------------------------------------------------------- -function _show(io::IO, ::MIME"image/png", plt::Plot{PlotlyBackend}) - # show_png_from_html(io, plt) - error("png output from the plotly backend is not supported. Please use plotlyjs instead.") -end - -function _show(io::IO, ::MIME"image/svg+xml", plt::Plot{PlotlyBackend}) - error("svg output from the plotly backend is not supported. Please use plotlyjs instead.") -end - function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) prepare_output(plt) write(io, html_head(plt) * html_body(plt)) diff --git a/src/output.jl b/src/output.jl index 6344ba9c..e4b7e657 100644 --- a/src/output.jl +++ b/src/output.jl @@ -195,10 +195,11 @@ function Base.show(io::IO, ::MIME"text/html", plt::Plot) end end -function _show(io::IO, m, plt::Plot{B}) where B - # Base.show_backtrace(STDOUT, backtrace()) - warn("_show is not defined for this backend. m=", string(m)) +# delegate mimewritable (showable on julia 0.7) to _show instead +function Base.mimewritable(m::M, plt::P) where {M<:MIME, P<:Plot} + return method_exists(_show, Tuple{IO, M, P}) end + function _display(plt::Plot) warn("_display is not defined for this backend.") end From ccb5194bb5ecb1a5623824f3d99938824c1a5be1 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 4 Jun 2018 10:18:59 +0200 Subject: [PATCH 682/720] make fallback method a method of _show instead of show fix #1529 --- src/backends/plotly.jl | 3 +-- src/backends/plotlyjs.jl | 5 ++--- src/output.jl | 9 ++------- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 64c9f21d..474efb68 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -922,8 +922,7 @@ end # ---------------------------------------------------------------- -function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) - prepare_output(plt) +function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyBackend}) write(io, html_head(plt) * html_body(plt)) end diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 1bcc3845..10213214 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -1,5 +1,5 @@ @require Revise begin - Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl")) + Revise.track(Plots, joinpath(Pkg.dir("Plots"), "src", "backends", "plotlyjs.jl")) end # https://github.com/spencerlyon2/PlotlyJS.jl @@ -88,8 +88,7 @@ end # ---------------------------------------------------------------- -function Base.show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) - prepare_output(plt) +function _show(io::IO, ::MIME"text/html", plt::Plot{PlotlyJSBackend}) if isijulia() && !_use_remote[] write(io, PlotlyJS.html_body(PlotlyJS.JupyterPlot(plt.o))) else diff --git a/src/output.jl b/src/output.jl index e4b7e657..55d677e3 100644 --- a/src/output.jl +++ b/src/output.jl @@ -177,7 +177,7 @@ const _best_html_output_type = KW( ) # a backup for html... passes to svg or png depending on the html_output_format arg -function Base.show(io::IO, ::MIME"text/html", plt::Plot) +function _show(io::IO, ::MIME"text/html", plt::Plot) output_type = Symbol(plt.attr[:html_output_format]) if output_type == :auto output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) @@ -191,7 +191,7 @@ function Base.show(io::IO, ::MIME"text/html", plt::Plot) elseif output_type == :txt show(io, MIME("text/plain"), plt) else - error("only png or svg allowed. got: $output_type") + error("only png or svg allowed. got: $(repr(output_type))") end end @@ -309,11 +309,6 @@ end out end - # default text/plain passes to html... handles Interact issues - function Base.show(io::IO, m::MIME"text/plain", plt::Plot) - show(io, MIME("text/html"), plt) - end - ENV["MPLBACKEND"] = "Agg" end end From 69a7a8a04e0bdf488c465b8a4930907f7a08e4d8 Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 4 Jun 2018 10:39:07 +0200 Subject: [PATCH 683/720] define show for more mime-types --- src/output.jl | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/output.jl b/src/output.jl index 55d677e3..a839464c 100644 --- a/src/output.jl +++ b/src/output.jl @@ -157,17 +157,6 @@ end # --------------------------------------------------------- -const _mimeformats = Dict( - "application/eps" => "eps", - "image/eps" => "eps", - "application/pdf" => "pdf", - "image/png" => "png", - "application/postscript" => "ps", - "image/svg+xml" => "svg", - "text/plain" => "txt", - "application/x-tex" => "tex", -) - const _best_html_output_type = KW( :pyplot => :png, :unicodeplots => :txt, @@ -205,8 +194,10 @@ function _display(plt::Plot) end # for writing to io streams... first prepare, then callback -for mime in keys(_mimeformats) - @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot{B}) where B +for mime in ("text/plain", "text/html", "image/png", "image/eps", "image/svg+xml", + "application/eps", "application/pdf", "application/postscript", + "application/x-tex") + @eval function Base.show(io::IO, m::MIME{Symbol($mime)}, plt::Plot) prepare_output(plt) _show(io, m, plt) end From 32ec9e82bf5273bde184b7f7ca0c2a05330f2dbe Mon Sep 17 00:00:00 2001 From: Fredrik Ekre Date: Mon, 4 Jun 2018 12:34:14 +0200 Subject: [PATCH 684/720] make UnicodePlots print to the given io and add support for text/plain in Plots own display_dict fix #1514 --- src/backends/unicodeplots.jl | 2 +- src/output.jl | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/backends/unicodeplots.jl b/src/backends/unicodeplots.jl index 6b4e124d..f644966d 100644 --- a/src/backends/unicodeplots.jl +++ b/src/backends/unicodeplots.jl @@ -212,7 +212,7 @@ end function _show(io::IO, ::MIME"text/plain", plt::Plot{UnicodePlotsBackend}) unicodeplots_rebuild(plt) - map(show, plt.o) + foreach(x -> show(io, x), plt.o) nothing end diff --git a/src/output.jl b/src/output.jl index a839464c..cebfe920 100644 --- a/src/output.jl +++ b/src/output.jl @@ -284,7 +284,10 @@ end output_type = get(_best_html_output_type, backend_name(plt.backend), :svg) end out = Dict() - if output_type == :png + if output_type == :txt + mime = "text/plain" + out[mime] = sprint(show, MIME(mime), plt) + elseif output_type == :png mime = "image/png" out[mime] = base64encode(show, MIME(mime), plt) elseif output_type == :svg From cbbd4fd02933f05a460d6e8ebcf2619c99e60b5f Mon Sep 17 00:00:00 2001 From: Will Grant Date: Wed, 6 Jun 2018 11:20:05 +1000 Subject: [PATCH 685/720] allow automatic widening of the axis limits to the next power of 10 with xlim/ylim = :round --- src/axes.jl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/axes.jl b/src/axes.jl index c873086e..f32d0ade 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -441,6 +441,13 @@ function default_should_widen(axis::Axis) should_widen end +function round_limits(amin,amax) + scale = 10^(1-round(log10(amax - amin))) + amin = floor(amin*scale)/scale + amax = ceil(amax*scale)/scale + amin, amax +end + # using the axis extrema and limit overrides, return the min/max value for this axis function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis)) ex = axis[:extrema] @@ -471,6 +478,8 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis) end elseif should_widen widen(amin, amax) + elseif lims == :round + round_limits(amin,amax) else amin, amax end From 91ed04ff83c6af7d36f114b827de9556739b1d6a Mon Sep 17 00:00:00 2001 From: Will Grant Date: Wed, 6 Jun 2018 18:44:07 +1000 Subject: [PATCH 686/720] update documentation in arg_desc with round limits option --- src/arg_desc.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index 199190db..a45ba315 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -110,7 +110,7 @@ const _arg_desc = KW( # axis args :guide => "String. Axis guide (label).", -:lims => "NTuple{2,Number}. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example).", +:lims => "NTuple{2,Number} or Symbol. Force axis limits. Only finite values are used (you can set only the right limit with `xlims = (-Inf, 2)` for example). `:round` widens the limit to the nearest round number ie. [0.1,3.6]=>[0.0,4.0]", :ticks => "Vector of numbers (set the tick values), Tuple of (tickvalues, ticklabels), or `:auto`", :scale => "Symbol. Scale of the axis: `:none`, `:ln`, `:log2`, `:log10`", :rotation => "Number. Degrees rotation of tick labels.", From 083721bbc161fd05c94846db24699fed02879dee Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 6 Jun 2018 18:25:22 +0200 Subject: [PATCH 687/720] fix single subplot in plotly --- src/backends/plotly.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 474efb68..933b78b3 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -328,9 +328,11 @@ function plotly_layout(plt::Plot) d_out[:annotations] = KW[] + multiple_subplots = length(plt.subplots) > 1 + for sp in plt.subplots - spidx = sp[:subplot_index] - x_idx, y_idx = plotly_link_indicies(plt, sp) + spidx = multiple_subplots ? sp[:subplot_index] : "" + x_idx, y_idx = multiple_subplots ? plotly_link_indicies(plt, sp) : ("", "") # add an annotation for the title... positioned horizontally relative to plotarea, # but vertically just below the top of the subplot bounding box if sp[:title] != "" From e96367cd4ba7bcd19bbfef43f829e7edbfb3d5f3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Tue, 12 Jun 2018 21:07:45 +0200 Subject: [PATCH 688/720] prepare release --- NEWS.md | 7 +++++++ test/imgcomp.jl | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index a39c748e..66f12baa 100644 --- a/NEWS.md +++ b/NEWS.md @@ -11,6 +11,13 @@ --- ## (current master) +## 0.17.2 +- fix single subplot in plotly +- implement `(xyz)lims = :round` +- PyPlot: fix bg_legend = invisible() +- set fallback tick specification for axes with discrete values +- restructure of show methods + ## 0.17.1 - Fix contour for PGFPlots - 32Bit fix: Int64 -> Int diff --git a/test/imgcomp.jl b/test/imgcomp.jl index d582e672..5a5a6cdd 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.17.1" +const _current_plots_version = v"0.17.2" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 781fea7431cb29ed6f3f94a0136708af6e332d10 Mon Sep 17 00:00:00 2001 From: yharel Date: Thu, 14 Jun 2018 02:59:04 +0300 Subject: [PATCH 689/720] Heatmap log scale fix --- src/backends/gr.jl | 3 +++ src/backends/plotly.jl | 2 ++ src/utils.jl | 14 ++++++-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ad235940..eae244a9 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -718,6 +718,9 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) end if st == :heatmap outside_ticks = true + for ax in (sp[:xaxis], sp[:yaxis]) + ax[:scale] != :identity && warn("GR: heatmap with $(ax[:scale]) scale not supported.") + end x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale]) xy_lims = x[1], x[end], y[1], y[end] expand_extrema!(sp[:xaxis], x) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 933b78b3..125f8182 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -587,6 +587,8 @@ function plotly_series(plt::Plot, series::Series) return plotly_series_segments(series, d_out, x, y, z) elseif st == :heatmap + x = heatmap_edges(x, sp[:xaxis][:scale]) + y = heatmap_edges(y, sp[:yaxis][:scale]) d_out[:type] = "heatmap" d_out[:x], d_out[:y], d_out[:z] = x, y, z d_out[:colorscale] = plotly_colorscale(series[:fillcolor], series[:fillalpha]) diff --git a/src/utils.jl b/src/utils.jl index 9c085f50..3a805733 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -358,19 +358,17 @@ const _scale_base = Dict{Symbol, Real}( :ln => e, ) -"create an (n+1) list of the outsides of heatmap rectangles" -function heatmap_edges(v::AVec, scale::Symbol = :identity) +function _heatmap_edges(v::AVec) vmin, vmax = ignorenan_extrema(v) extra_min = extra_max = 0.5 * (vmax-vmin) / (length(v)-1) - if scale in _logScales - vmin > 0 || error("The axis values must be positive for a $scale scale") - while vmin - extra_min <= 0 - extra_min /= _scale_base[scale] - end - end vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max) end +"create an (n+1) list of the outsides of heatmap rectangles" +function heatmap_edges(v::AVec, scale::Symbol = :identity) + f, invf = scalefunc(scale), invscalefunc(scale) + map(invf, _heatmap_edges(map(f,v))) +end function calc_r_extrema(x, y) xmin, xmax = ignorenan_extrema(x) From dc31cd71037fc080878ba8a915a630880f9d5978 Mon Sep 17 00:00:00 2001 From: yha Date: Sat, 16 Jun 2018 03:10:48 +0300 Subject: [PATCH 690/720] A better heuristic for outer heatmap edges --- src/utils.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.jl b/src/utils.jl index 3a805733..2334d96a 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -360,7 +360,8 @@ const _scale_base = Dict{Symbol, Real}( function _heatmap_edges(v::AVec) vmin, vmax = ignorenan_extrema(v) - extra_min = extra_max = 0.5 * (vmax-vmin) / (length(v)-1) + extra_min = (v[2] - v[1]) / 2 + extra_max = (v[end] - v[end - 1]) / 2 vcat(vmin-extra_min, 0.5 * (v[1:end-1] + v[2:end]), vmax+extra_max) end From 1e3d10ad318780b3ca9f2432c701efe743d22fa4 Mon Sep 17 00:00:00 2001 From: yha Date: Sat, 16 Jun 2018 03:13:13 +0300 Subject: [PATCH 691/720] GR heatmap: warning for non-equal spacing --- src/backends/gr.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index eae244a9..6c913183 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -719,7 +719,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st == :heatmap outside_ticks = true for ax in (sp[:xaxis], sp[:yaxis]) - ax[:scale] != :identity && warn("GR: heatmap with $(ax[:scale]) scale not supported.") + v = series[ax[:letter]] + if diff(collect(extrema(diff(v)))) > 1e-6*std(v) + warn("GR: heatmap only supported with equally spaced data.") + end end x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale]) xy_lims = x[1], x[end], y[1], y[end] From 00483d4c0d8adea96570b56e192978b3c79e8442 Mon Sep 17 00:00:00 2001 From: yha Date: Sat, 16 Jun 2018 03:13:13 +0300 Subject: [PATCH 692/720] GR heatmap: warning for non-equal spacing --- src/backends/gr.jl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index eae244a9..65f79042 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -719,7 +719,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if st == :heatmap outside_ticks = true for ax in (sp[:xaxis], sp[:yaxis]) - ax[:scale] != :identity && warn("GR: heatmap with $(ax[:scale]) scale not supported.") + v = series[ax[:letter]] + if diff(collect(extrema(diff(v))))[1] > 1e-6*std(v) + warn("GR: heatmap only supported with equally spaced data.") + end end x, y = heatmap_edges(series[:x], sp[:xaxis][:scale]), heatmap_edges(series[:y], sp[:yaxis][:scale]) xy_lims = x[1], x[end], y[1], y[end] From 3e66c6cce43f7ca2af6dc2253f0b815820d8f188 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 11:51:49 +0200 Subject: [PATCH 693/720] change DPI value back --- src/arg_desc.jl | 1 + src/args.jl | 1 + src/backends/gr.jl | 31 +++++++++++++------------------ src/backends/pyplot.jl | 6 +++--- src/output.jl | 6 +++++- 5 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index a45ba315..d5a6436d 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -65,6 +65,7 @@ const _arg_desc = KW( :html_output_format => "Symbol. When writing html output, what is the format? `:png` and `:svg` are currently supported.", :inset_subplots => "nothing or vector of 2-tuple (parent,bbox). optionally pass a vector of (parent,bbox) tuples which are the parent layout and the relative bounding box of inset subplots", :dpi => "Number. Dots Per Inch of output figures", +:thickness_scaling => "Number. Scale for the thickness of all line elements like lines, borders, axes, grid lines, ... defaults to 1.", :display_type => "Symbol (`:auto`, `:gui`, or `:inline`). When supported, `display` will either open a GUI window or plot inline.", :extra_kwargs => "KW (Dict{Symbol,Any}). Pass a map of extra keyword args which may be specific to a backend.", :fontfamily => "String or Symbol. Default font family for title, legend entries, tick labels and guides", diff --git a/src/args.jl b/src/args.jl index c9800eb6..bd6670dc 100644 --- a/src/args.jl +++ b/src/args.jl @@ -301,6 +301,7 @@ const _plot_defaults = KW( :inset_subplots => nothing, # optionally pass a vector of (parent,bbox) tuples which are # the parent layout and the relative bounding box of inset subplots :dpi => DPI, # dots per inch for images, etc + :thickness_scaling => 1, :display_type => :auto, :extra_kwargs => KW(), ) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index ad235940..2ab5a633 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -383,7 +383,7 @@ end function gr_set_line(lw, style, c) #, a) GR.setlinetype(gr_linetype[style]) w, h = gr_plot_size - GR.setlinewidth(max(0, lw / ((w + h) * 0.001))) + GR.setlinewidth(_gr_dpi_factor[1] * max(0, lw / ((w + h) * 0.001))) gr_set_linecolor(c) #, a) end @@ -396,6 +396,7 @@ end # this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses) const _gr_point_mult = 0.0018 * ones(1) +const _gr_dpi_factor = ones(1) # set the font attributes... assumes _gr_point_mult has been populated already function gr_set_font(f::Font; halign = f.halign, valign = f.valign, @@ -550,25 +551,18 @@ function gr_display(plt::Plot, fmt="") # compute the viewport_canvas, normalized to the larger dimension viewport_canvas = Float64[0,1,0,1] w, h = plt[:size] - if !haskey(ENV, "PLOTS_TEST") - dpi_factor = plt[:dpi] / DPI - if fmt == "png" - dpi_factor *= 6 - end - else - dpi_factor = 1 - end + dpi_factor = plt[:dpi] / DPI * plt[:thickness_scaling] gr_plot_size[:] = [w, h] if w > h ratio = float(h) / w - msize = display_width_ratio * w * dpi_factor + msize = display_width_ratio * w GR.setwsviewport(0, msize, 0, msize * ratio) GR.setwswindow(0, 1, 0, ratio) viewport_canvas[3] *= ratio viewport_canvas[4] *= ratio else ratio = float(w) / h - msize = display_height_ratio * h * dpi_factor + msize = display_height_ratio * h GR.setwsviewport(0, msize * ratio, 0, msize) GR.setwswindow(0, ratio, 0, 1) viewport_canvas[1] *= ratio @@ -580,7 +574,8 @@ function gr_display(plt::Plot, fmt="") # update point mult px_per_pt = px / pt - _gr_point_mult[1] = 1.5 * px_per_pt / max(h,w) + _gr_point_mult[1] = 1.5 * dpi_factor * px_per_pt / max(h,w) + _gr_dpi_factor[1] = dpi_factor # subplots: for sp in plt.subplots @@ -638,13 +633,13 @@ function _update_min_padding!(sp::Subplot{GRBackend}) bottompad = 2mm + sp[:bottom_margin] # Add margin for title if sp[:title] != "" - toppad += 5mm + toppad += 5mm * _gr_dpi_factor[1] end # Add margin for x and y ticks xticks, yticks = axis_drawing_info(sp)[1:2] if !(xticks in (nothing, false, :none)) flip, mirror = gr_set_xticks_font(sp) - l = gr_get_ticks_size(xticks, 2) + l = _gr_dpi_factor[1] * gr_get_ticks_size(xticks, 2) if mirror toppad += 1mm + gr_plot_size[2] * l * px else @@ -653,7 +648,7 @@ function _update_min_padding!(sp::Subplot{GRBackend}) end if !(yticks in (nothing, false, :none)) flip, mirror = gr_set_yticks_font(sp) - l = gr_get_ticks_size(yticks, 1) + l = _gr_dpi_factor[1] * gr_get_ticks_size(yticks, 1) if mirror rightpad += 1mm + gr_plot_size[1] * l * px else @@ -662,11 +657,11 @@ function _update_min_padding!(sp::Subplot{GRBackend}) end # Add margin for x label if sp[:xaxis][:guide] != "" - bottompad += 4mm + bottompad += 4mm * _gr_dpi_factor[1] end # Add margin for y label if sp[:yaxis][:guide] != "" - leftpad += 4mm + leftpad += 4mm * _gr_dpi_factor[1] end sp.minpad = (leftpad, toppad, rightpad, bottompad) end @@ -769,7 +764,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the axes gr_set_font(tickfont(xaxis)) - GR.setlinewidth(1) + GR.setlinewidth(_gr_dpi_factor[1]) if is3d(sp) zmin, zmax = gr_lims(zaxis, true) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 0110d086..9b86b1dd 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -395,7 +395,7 @@ function py_bbox_title(ax) end function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz) - ptsz * plt[:dpi] / DPI + ptsz * plt[:thickness_scaling] end # --------------------------------------------------------------------------- @@ -955,7 +955,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) w, h = plt[:size] fig = plt.o fig[:clear]() - dpi = plt[:dpi] + dpi = 100 * plt[:dpi] / DPI fig[:set_size_inches](w/dpi, h/dpi, forward = true) fig[set_facecolor_sym](py_color(plt[:background_color_outside])) fig[:set_dpi](dpi) @@ -1358,7 +1358,7 @@ for (mime, fmt) in _pyplot_mimeformats # figsize = map(px2inch, plt[:size]), facecolor = fig[:get_facecolor](), edgecolor = "none", - dpi = plt[:dpi] + dpi = 100 * plt[:dpi] / DPI ) end end diff --git a/src/output.jl b/src/output.jl index cebfe920..4d64f85d 100644 --- a/src/output.jl +++ b/src/output.jl @@ -324,13 +324,17 @@ end function Juno.render(pane::Juno.PlotPane, plt::Plot) # temporarily overwrite size to be Atom.plotsize sz = plt[:size] + dpi = plt[:dpi] jsize = Juno.plotsize() jsize[1] == 0 && (jsize[1] = 400) jsize[2] == 0 && (jsize[2] = 500) - plt[:size] = jsize + scale = minimum(jsize[i] / sz[i] for i in 1:2) + plt[:size] = (s * scale for s in sz) + plt[:dpi] *= scale Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz + plt[:dpi] = dpi end # special handling for PlotlyJS function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) From 0f13551b6dd89e9a01709e2186b1a7327c3891df Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 16:57:07 +0200 Subject: [PATCH 694/720] fix margins on gr --- src/backends/gr.jl | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 2ab5a633..1a4400b5 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -543,6 +543,8 @@ end function gr_display(plt::Plot, fmt="") GR.clearws() + _gr_dpi_factor[1] = plt[:dpi] / DPI * plt[:thickness_scaling] + # collect some monitor/display sizes in meters and pixels display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize() display_width_ratio = display_width_meters / display_width_px @@ -551,7 +553,6 @@ function gr_display(plt::Plot, fmt="") # compute the viewport_canvas, normalized to the larger dimension viewport_canvas = Float64[0,1,0,1] w, h = plt[:size] - dpi_factor = plt[:dpi] / DPI * plt[:thickness_scaling] gr_plot_size[:] = [w, h] if w > h ratio = float(h) / w @@ -574,8 +575,7 @@ function gr_display(plt::Plot, fmt="") # update point mult px_per_pt = px / pt - _gr_point_mult[1] = 1.5 * dpi_factor * px_per_pt / max(h,w) - _gr_dpi_factor[1] = dpi_factor + _gr_point_mult[1] = 1.5 * _gr_dpi_factor[1] * px_per_pt / max(h,w) # subplots: for sp in plt.subplots @@ -621,6 +621,7 @@ function gr_get_ticks_size(ticks, i) end function _update_min_padding!(sp::Subplot{GRBackend}) + dpi = sp.plt[:thickness_scaling] * sp.plt[:dpi] / Plots.DPI if !haskey(ENV, "GKSwstype") if isijulia() || (isdefined(Main, :Juno) && Juno.isactive()) ENV["GKSwstype"] = "svg" @@ -633,13 +634,13 @@ function _update_min_padding!(sp::Subplot{GRBackend}) bottompad = 2mm + sp[:bottom_margin] # Add margin for title if sp[:title] != "" - toppad += 5mm * _gr_dpi_factor[1] + toppad += 5mm end # Add margin for x and y ticks xticks, yticks = axis_drawing_info(sp)[1:2] if !(xticks in (nothing, false, :none)) flip, mirror = gr_set_xticks_font(sp) - l = _gr_dpi_factor[1] * gr_get_ticks_size(xticks, 2) + l = gr_get_ticks_size(xticks, 2) if mirror toppad += 1mm + gr_plot_size[2] * l * px else @@ -648,7 +649,7 @@ function _update_min_padding!(sp::Subplot{GRBackend}) end if !(yticks in (nothing, false, :none)) flip, mirror = gr_set_yticks_font(sp) - l = _gr_dpi_factor[1] * gr_get_ticks_size(yticks, 1) + l = gr_get_ticks_size(yticks, 1) if mirror rightpad += 1mm + gr_plot_size[1] * l * px else @@ -657,13 +658,13 @@ function _update_min_padding!(sp::Subplot{GRBackend}) end # Add margin for x label if sp[:xaxis][:guide] != "" - bottompad += 4mm * _gr_dpi_factor[1] + bottompad += 4mm end # Add margin for y label if sp[:yaxis][:guide] != "" - leftpad += 4mm * _gr_dpi_factor[1] + leftpad += 4mm end - sp.minpad = (leftpad, toppad, rightpad, bottompad) + sp.minpad = Tuple(dpi * pad for pad in (leftpad, toppad, rightpad, bottompad)) end function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) @@ -764,7 +765,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the axes gr_set_font(tickfont(xaxis)) - GR.setlinewidth(_gr_dpi_factor[1]) + GR.setlinewidth(sp.plt[:thickness_scaling] * sp.plt[:dpi] / Plots.DPI) if is3d(sp) zmin, zmax = gr_lims(zaxis, true) From 84ec8d61aed1de5c1e80e812be6d0548c1657b92 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 17:14:19 +0200 Subject: [PATCH 695/720] fix thickness_scaling in pyplot --- src/backends/pyplot.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 9b86b1dd..c6341549 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -395,7 +395,7 @@ function py_bbox_title(ax) end function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz) - ptsz * plt[:thickness_scaling] + ptsz end # --------------------------------------------------------------------------- @@ -955,7 +955,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) w, h = plt[:size] fig = plt.o fig[:clear]() - dpi = 100 * plt[:dpi] / DPI + dpi = 100 * plt[:thickness_scaling] * plt[:dpi] / DPI fig[:set_size_inches](w/dpi, h/dpi, forward = true) fig[set_facecolor_sym](py_color(plt[:background_color_outside])) fig[:set_dpi](dpi) @@ -1358,7 +1358,7 @@ for (mime, fmt) in _pyplot_mimeformats # figsize = map(px2inch, plt[:size]), facecolor = fig[:get_facecolor](), edgecolor = "none", - dpi = 100 * plt[:dpi] / DPI + dpi = 100 * plt[:thickness_scaling] * plt[:dpi] / DPI ) end end From 4847752ef45757839eb0eb826299a0eb8eaf6db1 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 19:24:58 +0200 Subject: [PATCH 696/720] make dpi change plot size --- src/backends/gr.jl | 15 ++++++++------- src/backends/pyplot.jl | 14 ++++++++------ src/output.jl | 5 ++++- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 1a4400b5..74a3dd62 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -543,7 +543,8 @@ end function gr_display(plt::Plot, fmt="") GR.clearws() - _gr_dpi_factor[1] = plt[:dpi] / DPI * plt[:thickness_scaling] + _gr_dpi_factor[1] = plt[:thickness_scaling] + dpi_factor = plt[:dpi] ./ Plots.DPI # collect some monitor/display sizes in meters and pixels display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize() @@ -556,14 +557,14 @@ function gr_display(plt::Plot, fmt="") gr_plot_size[:] = [w, h] if w > h ratio = float(h) / w - msize = display_width_ratio * w + msize = display_width_ratio * w * dpi_factor GR.setwsviewport(0, msize, 0, msize * ratio) GR.setwswindow(0, 1, 0, ratio) viewport_canvas[3] *= ratio viewport_canvas[4] *= ratio else ratio = float(w) / h - msize = display_height_ratio * h + msize = display_height_ratio * h * dpi_factor GR.setwsviewport(0, msize * ratio, 0, msize) GR.setwswindow(0, ratio, 0, 1) viewport_canvas[1] *= ratio @@ -621,14 +622,14 @@ function gr_get_ticks_size(ticks, i) end function _update_min_padding!(sp::Subplot{GRBackend}) - dpi = sp.plt[:thickness_scaling] * sp.plt[:dpi] / Plots.DPI + dpi = sp.plt[:thickness_scaling] if !haskey(ENV, "GKSwstype") if isijulia() || (isdefined(Main, :Juno) && Juno.isactive()) ENV["GKSwstype"] = "svg" end end # Add margin given by the user - leftpad = 2mm + sp[:left_margin] + leftpad = 4mm + sp[:left_margin] toppad = 2mm + sp[:top_margin] rightpad = 4mm + sp[:right_margin] bottompad = 2mm + sp[:bottom_margin] @@ -664,7 +665,7 @@ function _update_min_padding!(sp::Subplot{GRBackend}) if sp[:yaxis][:guide] != "" leftpad += 4mm end - sp.minpad = Tuple(dpi * pad for pad in (leftpad, toppad, rightpad, bottompad)) + sp.minpad = Tuple(dpi * [leftpad, toppad, rightpad, bottompad]) end function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) @@ -765,7 +766,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the axes gr_set_font(tickfont(xaxis)) - GR.setlinewidth(sp.plt[:thickness_scaling] * sp.plt[:dpi] / Plots.DPI) + GR.setlinewidth(sp.plt[:thickness_scaling]) if is3d(sp) zmin, zmax = gr_lims(zaxis, true) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index c6341549..5d3e5a23 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -402,7 +402,7 @@ end # Create the window/figure for this backend. function _create_backend_figure(plt::Plot{PyPlotBackend}) - w,h = map(px2inch, plt[:size]) + w,h = map(px2inch, Tuple(s * plt[:dpi] / Plots.DPI for s in plt[:size])) # # reuse the current figure? fig = if plt[:overwrite_figure] @@ -955,10 +955,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) w, h = plt[:size] fig = plt.o fig[:clear]() - dpi = 100 * plt[:thickness_scaling] * plt[:dpi] / DPI - fig[:set_size_inches](w/dpi, h/dpi, forward = true) + dpi = plt[:thickness_scaling] * plt[:dpi] + fig[:set_size_inches](w/DPI/plt[:thickness_scaling], h/DPI/plt[:thickness_scaling], forward = true) fig[set_facecolor_sym](py_color(plt[:background_color_outside])) - fig[:set_dpi](dpi) + fig[:set_dpi](plt[:dpi]) # resize the window PyPlot.plt[:get_current_fig_manager]()[:resize](w, h) @@ -1209,7 +1209,9 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend}) rightpad += sp[:right_margin] bottompad += sp[:bottom_margin] - sp.minpad = (leftpad, toppad, rightpad, bottompad) + dpi_factor = sp.plt[:thickness_scaling] * Plots.DPI / sp.plt[:dpi] + + sp.minpad = Tuple(dpi_factor .* [leftpad, toppad, rightpad, bottompad]) end @@ -1358,7 +1360,7 @@ for (mime, fmt) in _pyplot_mimeformats # figsize = map(px2inch, plt[:size]), facecolor = fig[:get_facecolor](), edgecolor = "none", - dpi = 100 * plt[:thickness_scaling] * plt[:dpi] / DPI + dpi = plt[:dpi] * plt[:thickness_scaling] ) end end diff --git a/src/output.jl b/src/output.jl index 4d64f85d..0e17894f 100644 --- a/src/output.jl +++ b/src/output.jl @@ -325,16 +325,19 @@ end # temporarily overwrite size to be Atom.plotsize sz = plt[:size] dpi = plt[:dpi] + thickness_scaling = plt[:thickness_scaling] jsize = Juno.plotsize() jsize[1] == 0 && (jsize[1] = 400) jsize[2] == 0 && (jsize[2] = 500) scale = minimum(jsize[i] / sz[i] for i in 1:2) plt[:size] = (s * scale for s in sz) - plt[:dpi] *= scale + plt[:dpi] = 100 + plt[:thickness_scaling] *= scale Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz plt[:dpi] = dpi + plt[:thickness_scaling] = thickness_scaling end # special handling for PlotlyJS function Juno.render(pane::Juno.PlotPane, plt::Plot{PlotlyJSBackend}) From 5ebcb77d0d17f30d73fdb9824ce507b1f0e4926f Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 19:29:28 +0200 Subject: [PATCH 697/720] rename _gr_dpi_scale to _gr_thickness_scaling --- src/backends/gr.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 74a3dd62..e6246e46 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -383,7 +383,7 @@ end function gr_set_line(lw, style, c) #, a) GR.setlinetype(gr_linetype[style]) w, h = gr_plot_size - GR.setlinewidth(_gr_dpi_factor[1] * max(0, lw / ((w + h) * 0.001))) + GR.setlinewidth(_gr_thickness_scaling[1] * max(0, lw / ((w + h) * 0.001))) gr_set_linecolor(c) #, a) end @@ -396,7 +396,7 @@ end # this stores the conversion from a font pointsize to "percentage of window height" (which is what GR uses) const _gr_point_mult = 0.0018 * ones(1) -const _gr_dpi_factor = ones(1) +const _gr_thickness_scaling = ones(1) # set the font attributes... assumes _gr_point_mult has been populated already function gr_set_font(f::Font; halign = f.halign, valign = f.valign, @@ -543,7 +543,7 @@ end function gr_display(plt::Plot, fmt="") GR.clearws() - _gr_dpi_factor[1] = plt[:thickness_scaling] + _gr_thickness_scaling[1] = plt[:thickness_scaling] dpi_factor = plt[:dpi] ./ Plots.DPI # collect some monitor/display sizes in meters and pixels @@ -576,7 +576,7 @@ function gr_display(plt::Plot, fmt="") # update point mult px_per_pt = px / pt - _gr_point_mult[1] = 1.5 * _gr_dpi_factor[1] * px_per_pt / max(h,w) + _gr_point_mult[1] = 1.5 * _gr_thickness_scaling[1] * px_per_pt / max(h,w) # subplots: for sp in plt.subplots From 76f2860c74d7c469893c168a026c895c94833884 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 16 Jun 2018 20:38:46 +0200 Subject: [PATCH 698/720] fix gr --- src/backends/gr.jl | 2 +- src/output.jl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e6246e46..b12dd1c4 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -544,7 +544,7 @@ function gr_display(plt::Plot, fmt="") GR.clearws() _gr_thickness_scaling[1] = plt[:thickness_scaling] - dpi_factor = plt[:dpi] ./ Plots.DPI + dpi_factor = plt[:dpi] / Plots.DPI # collect some monitor/display sizes in meters and pixels display_width_meters, display_height_meters, display_width_px, display_height_px = GR.inqdspsize() diff --git a/src/output.jl b/src/output.jl index 0e17894f..1f9da687 100644 --- a/src/output.jl +++ b/src/output.jl @@ -332,7 +332,7 @@ end scale = minimum(jsize[i] / sz[i] for i in 1:2) plt[:size] = (s * scale for s in sz) - plt[:dpi] = 100 + plt[:dpi] = Plots.DPI plt[:thickness_scaling] *= scale Juno.render(pane, HTML(stringmime(MIME("text/html"), plt))) plt[:size] = sz From 534c7799e5a7f06af90856934214d168da47cf29 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 17 Jun 2018 22:20:20 +0200 Subject: [PATCH 699/720] fix markercolor as vector on pyplot --- src/backends/pyplot.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 0110d086..3d72ab12 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1270,8 +1270,8 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), linestyle = py_linestyle(:path, get_linestyle(series)), marker = py_marker(series[:markershape]), - markeredgecolor = py_markerstrokecolor(series), - markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5]) + markeredgecolor = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)), + markerfacecolor = series[:marker_z] == nothing ? py_color(get_markercolor(series), get_markeralpha(series)) : py_color(series[:markercolor][0.5]) ) else series[:serieshandle][1] From 00f285cba3157360024b7813b890448c520c3bd1 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 18 Jun 2018 19:45:43 +0200 Subject: [PATCH 700/720] fix pyplot fillrange --- src/backends/pyplot.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 0110d086..29c7b09b 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -837,9 +837,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) end n = length(dim1) args = if typeof(fillrange) <: Union{Real, AVec} - dim1, expand_data(fillrange, n), dim2 + dim1, _cycle(fillrange, rng), dim2 elseif is_2tuple(fillrange) - dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) + dim1, _cycle(fillrange[1], rng), _cycle(fillrange[2], rng) end handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); From 2ed0f1661adb2c46711b4180857b8dd56000c8e7 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 18 Jun 2018 19:55:09 +0200 Subject: [PATCH 701/720] fix plotly fillrange --- src/backends/plotly.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 125f8182..8b7e484b 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -332,7 +332,7 @@ function plotly_layout(plt::Plot) for sp in plt.subplots spidx = multiple_subplots ? sp[:subplot_index] : "" - x_idx, y_idx = multiple_subplots ? plotly_link_indicies(plt, sp) : ("", "") + x_idx, y_idx = multiple_subplots ? plotly_link_indicies(plt, sp) : ("", "") # add an annotation for the title... positioned horizontally relative to plotarea, # but vertically just below the top of the subplot bounding box if sp[:title] != "" @@ -805,7 +805,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) series[:fillrange] = (f1, f2) end if isa(series[:fillrange], AbstractVector) - d_out_fillrange[:y] = series[:fillrange] + d_out_fillrange[:y] = series[:fillrange][rng] delete!(d_out_fillrange, :fill) delete!(d_out_fillrange, :fillcolor) else From 124c838e06fbc1817a6f1648f47f06335e7bfb12 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 22 Jun 2018 22:07:00 +0200 Subject: [PATCH 702/720] fix flip for heatmap and image on GR --- src/backends/gr.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/backends/gr.jl b/src/backends/gr.jl index 65f79042..22f66fd8 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -1095,6 +1095,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :heatmap xmin, xmax, ymin, ymax = xy_lims zmin, zmax = clims + m, n = length(x), length(y) + xinds = sort(1:m, rev = xaxis[:flip]) + yinds = sort(1:n, rev = yaxis[:flip]) + z = reshape(reshape(z, m, n)[xinds, yinds], m*n) GR.setspace(zmin, zmax, 0, 90) grad = isa(series[:fillcolor], ColorGradient) ? series[:fillcolor] : cgrad() colors = [plot_color(grad[clamp((zi-zmin) / (zmax-zmin), 0, 1)], series[:fillalpha]) for zi=z] @@ -1198,7 +1202,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) elseif st == :image z = transpose_z(series, series[:z].surf, true)' - w, h = size(z) + w, h = length(x), length(y) + xinds = sort(1:w, rev = xaxis[:flip]) + yinds = sort(1:h, rev = yaxis[:flip]) + z = z[xinds, yinds] xmin, xmax = ignorenan_extrema(series[:x]); ymin, ymax = ignorenan_extrema(series[:y]) if eltype(z) <: Colors.AbstractGray grey = round.(UInt8, float(z) * 255) From 865ac52442db347a88e35e788d80ed6f0d8df464 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 23 Jun 2018 19:39:25 +0200 Subject: [PATCH 703/720] pgf_thickness_scaling for series linewidths and markers --- src/backends/pgfplots.jl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 19155c92..baa2eec0 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -149,6 +149,10 @@ function pgf_colormap(grad::ColorGradient) end,", ") end +pgf_thickness_scaling(plt::Plot) = plt[:thickness_scaling] * plt[:dpi] / DPI +pgf_thickness_scaling(sp::Subplot) = pgf_thickness_scaling(sp.plt) +pgf_thickness_scaling(series) = pgf_thickness_scaling(series[:subplot]) + function pgf_fillstyle(d, i = 1) cstr,a = pgf_color(get_fillcolor(d, i)) fa = get_fillalpha(d, i) @@ -167,7 +171,7 @@ function pgf_linestyle(d, i = 1) """ color = $cstr, draw opacity=$a, - line width=$(get_linewidth(d, i)), + line width=$(pgf_thickness_scaling(d) * get_linewidth(d, i)), $(get(_pgfplots_linestyles, get_linestyle(d, i), "solid"))""" end @@ -177,11 +181,11 @@ function pgf_marker(d, i = 1) cstr_stroke, a_stroke = pgf_color(plot_color(get_markerstrokecolor(d, i), get_markerstrokealpha(d, i))) """ mark = $(get(_pgfplots_markers, shape, "*")), - mark size = $(0.5 * _cycle(d[:markersize], i)), + mark size = $(pgf_thickness_scaling(d) * 0.5 * _cycle(d[:markersize], i)), mark options = { color = $cstr_stroke, draw opacity = $a_stroke, fill = $cstr, fill opacity = $a, - line width = $(_cycle(d[:markerstrokewidth], i)), + line width = $(pgf_thickness_scaling(d) * _cycle(d[:markerstrokewidth], i)), rotate = $(shape == :dtriangle ? 180 : 0), $(get(_pgfplots_linestyles, _cycle(d[:markerstrokestyle], i), "solid")) }""" From 624a181b23b363dbdc4c9173e515851a4a7be5d3 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 23 Jun 2018 21:47:01 +0200 Subject: [PATCH 704/720] implement axis and grid arguments and corresponding thickness_scaling --- src/backends/pgfplots.jl | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index baa2eec0..53a30aec 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -162,17 +162,21 @@ function pgf_fillstyle(d, i = 1) "fill = $cstr, fill opacity=$a" end -function pgf_linestyle(d, i = 1) - cstr,a = pgf_color(get_linecolor(d, i)) - la = get_linealpha(d, i) - if la != nothing - a = la - end +function pgf_linestyle(linewidth::Real, color, alpha = 1, linestyle = "solid") + cstr, a = pgf_color(plot_color(color, alpha)) """ color = $cstr, - draw opacity=$a, - line width=$(pgf_thickness_scaling(d) * get_linewidth(d, i)), - $(get(_pgfplots_linestyles, get_linestyle(d, i), "solid"))""" + draw opacity = $a, + line width = $linewidth, + $(get(_pgfplots_linestyles, linestyle, "solid"))""" +end + +function pgf_linestyle(d, i = 1) + lw = pgf_thickness_scaling(d) * get_linewidth(d, i) + lc = get_linecolor(d, i) + la = get_linealpha(d, i) + ls = get_linestyle(d, i) + return pgf_linestyle(lw, lc, la, ls) end function pgf_marker(d, i = 1) @@ -431,6 +435,7 @@ function pgf_axis(sp::Subplot, letter) push!(style, string(letter, "ticklabels = {}")) end push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside"))) + push!(style, string(letter, " grid style = {", pgf_linestyle(pgf_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle]), "}")) end # framestyle @@ -443,7 +448,7 @@ function pgf_axis(sp::Subplot, letter) if framestyle == :zerolines push!(style, string("extra ", letter, " ticks = 0")) push!(style, string("extra ", letter, " tick labels = ")) - push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {color = black, draw opacity=1.0, line width=0.5), solid}}")) + push!(style, string("extra ", letter, " tick style = {grid = major, major grid style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_axis], 1.0), "}}")) end if !axis[:showaxis] @@ -451,6 +456,8 @@ function pgf_axis(sp::Subplot, letter) end if !axis[:showaxis] || framestyle in (:zerolines, :grid, :none) push!(style, string(letter, " axis line style = {draw opacity = 0}")) + else + push!(style, string(letter, " axis line style = {", pgf_linestyle(pgf_thickness_scaling(sp), axis[:foreground_color_axis], 1.0), "}")) end # return the style list and KW args @@ -505,6 +512,8 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) if haskey(_pgfplots_legend_pos, legpos) kw[:legendPos] = _pgfplots_legend_pos[legpos] end + cstr, a = pgf_color(plot_color(sp[:background_color_legend])) + push!(style, string("legend style = {", pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], 1.0, "solid"), ",", "fill = $cstr", "}")) if any(s[:seriestype] == :contour for s in series_list(sp)) kw[:view] = "{0}{90}" From 77a82eaa6aac21d6ee715288c09457a6e9218bc2 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 23 Jun 2018 23:24:09 +0200 Subject: [PATCH 705/720] implent font size and colors --- src/backends/pgfplots.jl | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 53a30aec..572c0ee2 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -8,11 +8,12 @@ end const _pgfplots_attr = merge_with_base_supported([ :annotations, - # :background_color_legend, + :background_color_legend, :background_color_inside, # :background_color_outside, - # :foreground_color_legend, :foreground_color_grid, :foreground_color_axis, - # :foreground_color_text, :foreground_color_border, + # :foreground_color_legend, + :foreground_color_grid, :foreground_color_axis, + :foreground_color_text, :foreground_color_border, :label, :seriescolor, :seriesalpha, :linecolor, :linestyle, :linewidth, :linealpha, @@ -162,8 +163,8 @@ function pgf_fillstyle(d, i = 1) "fill = $cstr, fill opacity=$a" end -function pgf_linestyle(linewidth::Real, color, alpha = 1, linestyle = "solid") - cstr, a = pgf_color(plot_color(color, alpha)) +function pgf_linestyle(linewidth::Real, color, α = 1, linestyle = "solid") + cstr, a = pgf_color(plot_color(color, α)) """ color = $cstr, draw opacity = $a, @@ -179,6 +180,11 @@ function pgf_linestyle(d, i = 1) return pgf_linestyle(lw, lc, la, ls) end +function pgf_font(fontsize, thickness_scaling = 1, font = "\\selectfont") + fs = fontsize * thickness_scaling + return string("{\\fontsize{", fs, " pt}{", 1.3fs, " pt}", font, "}") +end + function pgf_marker(d, i = 1) shape = _cycle(d[:markershape], i) cstr, a = pgf_color(plot_color(get_markercolor(d, i), get_markeralpha(d, i))) @@ -381,6 +387,10 @@ function pgf_axis(sp::Subplot, letter) # Add ticklabel rotations push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}") + # Add label font + cstr, α = pgf_color(plot_color(axis[:guidefontcolor])) + push!(style, string(letter, "label style = {font = ", pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) + # flip/reverse? axis[:flip] && push!(style, "$letter dir=reverse") @@ -435,6 +445,8 @@ function pgf_axis(sp::Subplot, letter) push!(style, string(letter, "ticklabels = {}")) end push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside"))) + cstr, α = pgf_color(plot_color(axis[:tickfontcolor])) + push!(style, string(letter, "ticklabel style = {font = ", pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) push!(style, string(letter, " grid style = {", pgf_linestyle(pgf_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle]), "}")) end @@ -502,6 +514,8 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) if sp[:title] != "" kw[:title] = "$(sp[:title])" + cstr, α = pgf_color(plot_color(sp[:titlefontcolor])) + push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) end if sp[:aspect_ratio] in (1, :equal) @@ -513,7 +527,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) kw[:legendPos] = _pgfplots_legend_pos[legpos] end cstr, a = pgf_color(plot_color(sp[:background_color_legend])) - push!(style, string("legend style = {", pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], 1.0, "solid"), ",", "fill = $cstr", "}")) + push!(style, string("legend style = {", pgf_linestyle(pgf_thickness_scaling(sp), sp[:foreground_color_legend], 1.0, "solid"), ",", "fill = $cstr,", "font = ", pgf_font(sp[:legendfontsize], pgf_thickness_scaling(sp)), "}")) if any(s[:seriestype] == :contour for s in series_list(sp)) kw[:view] = "{0}{90}" From 652e2f27b6b44bf0a109752bcd163aa154097d57 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 23 Jun 2018 23:38:38 +0200 Subject: [PATCH 706/720] implement font rotation --- src/backends/pgfplots.jl | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index 572c0ee2..dce8350a 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -384,12 +384,9 @@ function pgf_axis(sp::Subplot, letter) # axis guide kw[Symbol(letter,:label)] = axis[:guide] - # Add ticklabel rotations - push!(style, "$(letter)ticklabel style={rotate = $(axis[:rotation])}") - # Add label font cstr, α = pgf_color(plot_color(axis[:guidefontcolor])) - push!(style, string(letter, "label style = {font = ", pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) + push!(style, string(letter, "label style = {font = ", pgf_font(axis[:guidefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:guidefontrotation], "}")) # flip/reverse? axis[:flip] && push!(style, "$letter dir=reverse") @@ -446,7 +443,7 @@ function pgf_axis(sp::Subplot, letter) end push!(style, string(letter, "tick align = ", (axis[:tick_direction] == :out ? "outside" : "inside"))) cstr, α = pgf_color(plot_color(axis[:tickfontcolor])) - push!(style, string(letter, "ticklabel style = {font = ", pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) + push!(style, string(letter, "ticklabel style = {font = ", pgf_font(axis[:tickfontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", axis[:tickfontrotation], "}")) push!(style, string(letter, " grid style = {", pgf_linestyle(pgf_thickness_scaling(sp) * axis[:gridlinewidth], axis[:foreground_color_grid], axis[:gridalpha], axis[:gridstyle]), "}")) end @@ -515,7 +512,7 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) if sp[:title] != "" kw[:title] = "$(sp[:title])" cstr, α = pgf_color(plot_color(sp[:titlefontcolor])) - push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, "}")) + push!(style, string("title style = {font = ", pgf_font(sp[:titlefontsize], pgf_thickness_scaling(sp)), ", color = ", cstr, ", draw opacity = ", α, ", rotate = ", sp[:titlefontrotation], "}")) end if sp[:aspect_ratio] in (1, :equal) From 2652990432e0c125a73c23ba4d61dfbe2ad3a26a Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sat, 23 Jun 2018 23:44:43 +0200 Subject: [PATCH 707/720] annotations --- src/backends/pgfplots.jl | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/backends/pgfplots.jl b/src/backends/pgfplots.jl index dce8350a..ac54173c 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -201,17 +201,18 @@ function pgf_marker(d, i = 1) }""" end -function pgf_add_annotation!(o,x,y,val) +function pgf_add_annotation!(o, x, y, val, thickness_scaling = 1) # Construct the style string. # Currently supports color and orientation cstr,a = pgf_color(val.font.color) push!(o, PGFPlots.Plots.Node(val.str, # Annotation Text - x, y, - style=""" - $(get(_pgf_annotation_halign,val.font.halign,"")), - color=$cstr, draw opacity=$(convert(Float16,a)), - rotate=$(val.font.rotation) - """)) + x, y, + style=""" + $(get(_pgf_annotation_halign,val.font.halign,"")), + color=$cstr, draw opacity=$(convert(Float16,a)), + rotate=$(val.font.rotation), + font=$(pgf_font(val.font.pointsize, thickness_scaling)) + """)) end # -------------------------------------------------------------------------------------- @@ -578,13 +579,13 @@ function _update_plot_object(plt::Plot{PGFPlotsBackend}) # 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)) + pgf_add_annotation!(o, xi, yi, PlotText(str, fnt), pgf_thickness_scaling(series)) end end # add the annotations for ann in sp[:annotations] - pgf_add_annotation!(o, locate_annotation(sp, ann...)...) + pgf_add_annotation!(o, locate_annotation(sp, ann...)..., pgf_thickness_scaling(sp)) end From 440622830a75ccd8b868340c55534f35c6a5677b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 24 Jun 2018 00:34:11 +0200 Subject: [PATCH 708/720] disregard dpi for pgfplots --- 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 ac54173c..aae1a356 100644 --- a/src/backends/pgfplots.jl +++ b/src/backends/pgfplots.jl @@ -150,7 +150,7 @@ function pgf_colormap(grad::ColorGradient) end,", ") end -pgf_thickness_scaling(plt::Plot) = plt[:thickness_scaling] * plt[:dpi] / DPI +pgf_thickness_scaling(plt::Plot) = plt[:thickness_scaling] pgf_thickness_scaling(sp::Subplot) = pgf_thickness_scaling(sp.plt) pgf_thickness_scaling(series) = pgf_thickness_scaling(series[:subplot]) From 61a2d962c070e5a20e934d729f10ce81ce811e19 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 24 Jun 2018 11:03:56 +0200 Subject: [PATCH 709/720] widen most seriestypes including logscales --- src/arg_desc.jl | 3 ++- src/args.jl | 1 + src/axes.jl | 20 +++++++++++--------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/arg_desc.jl b/src/arg_desc.jl index d5a6436d..56e3719d 100644 --- a/src/arg_desc.jl +++ b/src/arg_desc.jl @@ -140,5 +140,6 @@ const _arg_desc = KW( :gridstyle => "Symbol. Style of the grid lines. Choose from $(_allStyles)", :gridlinewidth => "Number. Width of the grid lines (in pixels)", :tick_direction => "Symbol. Direction of the ticks. `:in` or `:out`", -:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`" +:showaxis => "Bool, Symbol or String. Show the axis. `true`, `false`, `:show`, `:hide`, `:yes`, `:no`, `:x`, `:y`, `:z`, `:xy`, ..., `:all`, `:off`", +:widen => "Bool. Widen the axis limits by a small factor to avoid cut-off markers and lines at the borders. Defaults to `true`.", ) diff --git a/src/args.jl b/src/args.jl index bd6670dc..671485d0 100644 --- a/src/args.jl +++ b/src/args.jl @@ -382,6 +382,7 @@ const _axis_defaults = KW( :gridlinewidth => 0.5, :tick_direction => :in, :showaxis => true, + :widen => true, ) const _suppress_warnings = Set{Symbol}([ diff --git a/src/axes.jl b/src/axes.jl index f32d0ade..1410b28b 100644 --- a/src/axes.jl +++ b/src/axes.jl @@ -418,21 +418,23 @@ end # ------------------------------------------------------------------------- # push the limits out slightly -function widen(lmin, lmax) - span = lmax - lmin +function widen(lmin, lmax, scale = :identity) + f, invf = scalefunc(scale), invscalefunc(scale) + span = f(lmax) - f(lmin) # eps = NaNMath.max(1e-16, min(1e-2span, 1e-10)) eps = NaNMath.max(1e-16, 0.03span) - lmin-eps, lmax+eps + invf(f(lmin)-eps), invf(f(lmax)+eps) end -# figure out if widening is a good idea. if there's a scale set it's too tricky, -# so lazy out and don't widen +# figure out if widening is a good idea. +const _widen_seriestypes = (:line, :path, :steppre, :steppost, :sticks, :scatter, :barbins, :barhist, :histogram, :scatterbins, :scatterhist, :stepbins, :stephist, :bins2d, :histogram2d, :bar, :shape, :path3d, :scatter3d) + function default_should_widen(axis::Axis) should_widen = false - if axis[:scale] == :identity && !is_2tuple(axis[:lims]) + if !is_2tuple(axis[:lims]) for sp in axis.sps for series in series_list(sp) - if series.d[:seriestype] in (:scatter,) || series.d[:markershape] != :none + if series.d[:seriestype] in _widen_seriestypes should_widen = true end end @@ -476,8 +478,8 @@ function axis_limits(axis::Axis, should_widen::Bool = default_should_widen(axis) else amin, amax end - elseif should_widen - widen(amin, amax) + elseif should_widen && axis[:widen] + widen(amin, amax, axis[:scale]) elseif lims == :round round_limits(amin,amax) else From 12c9a8e6c3d4f9a462de9b555c4cbd52b6956395 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 24 Jun 2018 19:01:06 +0200 Subject: [PATCH 710/720] plots_heatmap --- src/recipes.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/recipes.jl b/src/recipes.jl index 2393f6a8..dfb1fd54 100644 --- a/src/recipes.jl +++ b/src/recipes.jl @@ -413,6 +413,7 @@ end z := nothing seriestype := :shape label := "" + widen --> false () end @deps plots_heatmap shape From 211be0a863b9fe11f2ed055bd714aad2be57e54c Mon Sep 17 00:00:00 2001 From: yharel Date: Mon, 25 Jun 2018 00:42:36 +0300 Subject: [PATCH 711/720] Setting axis scale regardless of ticks --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 8b7e484b..1daa9d26 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -263,6 +263,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) end ax[:tickangle] = -axis[:rotation] + ax[:type] = plotly_scale(axis[:scale]) lims = axis_limits(axis) if axis[:ticks] != :native || axis[:lims] != :auto @@ -271,7 +272,6 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) if !(axis[:ticks] in (nothing, :none, false)) ax[:titlefont] = plotly_font(guidefont(axis)) - ax[:type] = plotly_scale(axis[:scale]) ax[:tickfont] = plotly_font(tickfont(axis)) ax[:tickcolor] = framestyle in (:zerolines, :grid) || !axis[:showaxis] ? rgba_string(invisible()) : rgb_string(axis[:foreground_color_axis]) ax[:linecolor] = rgba_string(axis[:foreground_color_axis]) From 371430c1728d7325064e95a3e63760d0cdd52cca Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Tue, 26 Jun 2018 12:18:22 +0100 Subject: [PATCH 712/720] Fix axis flip on Plotly. --- src/backends/plotly.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1daa9d26..bab0a1c3 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -278,7 +278,7 @@ function plotly_axis(plt::Plot, axis::Axis, sp::Subplot) # flip if axis[:flip] - ax[:autorange] = "reversed" + ax[:range] = reverse(ax[:range]) end # ticks From ee73e32b0e2ab9e34b76c81d3c433966eab79952 Mon Sep 17 00:00:00 2001 From: Andrew Palugniok Date: Tue, 26 Jun 2018 18:26:13 +0100 Subject: [PATCH 713/720] Fix hover and zcolor interaction in Plotly. --- src/backends/plotly.jl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backends/plotly.jl b/src/backends/plotly.jl index 1daa9d26..a388dd5f 100644 --- a/src/backends/plotly.jl +++ b/src/backends/plotly.jl @@ -789,7 +789,7 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z) end plotly_polar!(d_out, series) - plotly_hover!(d_out, series[:hover]) + plotly_hover!(d_out, _cycle(series[:hover], rng)) if hasfillrange # if hasfillrange is true, return two dictionaries (one for original @@ -840,6 +840,7 @@ function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol) cmin, cmax = get_clims(series[:subplot]) d_out[:showlegend] = false d_out[:type] = is3d(series) ? :scatter3d : :scatter + d_out[:hoverinfo] = :none d_out[:mode] = :markers d_out[:x], d_out[:y] = [series[:x][1]], [series[:y][1]] if is3d(series) @@ -848,6 +849,7 @@ function plotly_colorbar_hack(series::Series, d_base::KW, sym::Symbol) # zrange = zmax == zmin ? 1 : zmax - zmin # if all marker_z values are the same, plot all markers same color (avoids division by zero in next line) d_out[:marker] = KW( :size => 0, + :opacity => 0, :color => [0.5], :cmin => cmin, :cmax => cmax, From 7085d98f41b5c5759e6cdd3c209acd50972e6ccf Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 27 Jun 2018 15:24:50 +0100 Subject: [PATCH 714/720] webio integration --- src/backends/plotlyjs.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 10213214..280d2f07 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -120,6 +120,12 @@ function _display(plt::Plot{PlotlyJSBackend}) end end +@require WebIO begin + function WebIO.render(plt::Plot{PlotlyJSBackend}) + _update_plot_object(plt) + WebIO.render(plt.o) + end +end function closeall(::PlotlyJSBackend) if !isplotnull() && isa(current().o, PlotlyJS.SyncPlot) From 35c17044e1aea882ba3704802afbb0717f62d734 Mon Sep 17 00:00:00 2001 From: Pietro Vertechi Date: Wed, 27 Jun 2018 15:39:54 +0100 Subject: [PATCH 715/720] prepare output --- src/backends/plotlyjs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backends/plotlyjs.jl b/src/backends/plotlyjs.jl index 280d2f07..e2883220 100644 --- a/src/backends/plotlyjs.jl +++ b/src/backends/plotlyjs.jl @@ -122,7 +122,7 @@ end @require WebIO begin function WebIO.render(plt::Plot{PlotlyJSBackend}) - _update_plot_object(plt) + prepare_output(plt) WebIO.render(plt.o) end end From 7d88a746eaf9276bb742f6c6576c9087015f7168 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 1 Jul 2018 09:27:11 +0200 Subject: [PATCH 716/720] don't checkout PlotUtils in tests --- test/travis_commands.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/travis_commands.jl b/test/travis_commands.jl index 91ab0ca6..a283d780 100644 --- a/test/travis_commands.jl +++ b/test/travis_commands.jl @@ -9,7 +9,7 @@ Pkg.clone("https://github.com/JuliaPlots/PlotReferenceImages.jl.git") # Pkg.clone("https://github.com/JuliaStats/KernelDensity.jl.git") Pkg.clone("StatPlots") -Pkg.checkout("PlotUtils") +# Pkg.checkout("PlotUtils") # Pkg.clone("Blink") # Pkg.build("Blink") From 2b48f50de430c4566d65b7b0ac41265598050b31 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Sun, 1 Jul 2018 10:06:49 +0200 Subject: [PATCH 717/720] prepare release --- NEWS.md | 15 ++++++++++++++- test/imgcomp.jl | 2 +- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 66f12baa..197ce33d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -3,13 +3,26 @@ #### notes on release changes, ongoing development, and future planned work -- All new development should target 0.15! +- Minor version 0.17 is the last one to support Julia 0.6!! - Minor version 0.11 is the last one to support Julia 0.5!! - Critical bugfixes only - `backports` branch is for Julia 0.5 --- ## (current master) +- All new development should target Julia 0.7! + +## 0.17.3 +- Log-scale heatmap edge computation +- Fix size and dpi for GR and PyPlot +- Fix fillrange with line segments on PyPlot and Plotly +- fix flip for heatmap and image on GR +- New attributes for PGFPlots +- Widen axes for most series types and log scales +- Plotly: fix log scale with no ticks +- Fix axis flip on Plotly +- Fix hover and zcolor interaction in Plotly +- WebIO integration for PlotlyJS backend ## 0.17.2 - fix single subplot in plotly diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 5a5a6cdd..625d6d77 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.17.2" +const _current_plots_version = v"0.17.3" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2) From 64ec922d7f1858b75c6666c984c41cc2047386ed Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 25 Jul 2018 23:32:02 +0200 Subject: [PATCH 718/720] fix thickness_scaling in pyplot --- src/backends/pyplot.jl | 67 ++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index fa86acc3..1adff445 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -394,8 +394,8 @@ function py_bbox_title(ax) bb end -function py_dpi_scale(plt::Plot{PyPlotBackend}, ptsz) - ptsz +function py_thickness_scale(plt::Plot{PyPlotBackend}, ptsz) + ptsz * plt[:thickness_scaling] end # --------------------------------------------------------------------------- @@ -505,7 +505,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # :label => series[:label], # :zorder => plt.n, # :cmap => py_linecolormap(series), - # :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), + # :linewidths => py_thickness_scale(plt, get_linewidth.(series, 1:n)), # :linestyle => py_linestyle(st, get_linestyle.(series)), # :norm => pycolors["Normalize"](; extrakw...) # ) @@ -530,7 +530,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = i == 1 ? series[:label] : "", zorder = series[:series_plotindex], color = py_color(get_linecolor(series, i), get_linealpha(series, i)), - linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linewidth = py_thickness_scale(plt, get_linewidth(series, i)), linestyle = py_linestyle(st, get_linestyle(series, i)), solid_capstyle = "round", drawstyle = py_stepstyle(st) @@ -550,7 +550,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :shrinkB => 0, :edgecolor => py_linecolor(series), :facecolor => py_linecolor(series), - :linewidth => py_dpi_scale(plt, get_linewidth(series)), + :linewidth => py_thickness_scale(plt, get_linewidth(series)), :linestyle => py_linestyle(st, get_linestyle(series)), ) add_arrows(x, y) do xyprev, xy @@ -589,7 +589,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) x,y = xyargs shapes = series[:markershape] msc = py_markerstrokecolor(series) - lw = py_dpi_scale(plt, series[:markerstrokewidth]) + lw = py_thickness_scale(plt, series[:markerstrokewidth]) for i=1:length(y) extrakw[:c] = _cycle(markercolor, i) @@ -597,7 +597,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex] + 0.5, marker = py_marker(_cycle(shapes,i)), - s = py_dpi_scale(plt, _cycle(series[:markersize],i) .^ 2), + s = py_thickness_scale(plt, _cycle(series[:markersize],i) .^ 2), edgecolors = msc, linewidths = lw, extrakw... @@ -610,9 +610,9 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex] + 0.5, marker = py_marker(series[:markershape]), - s = py_dpi_scale(plt, series[:markersize] .^ 2), + s = py_thickness_scale(plt, series[:markersize] .^ 2), edgecolors = py_markerstrokecolor(series), - linewidths = py_dpi_scale(plt, series[:markerstrokewidth]), + linewidths = py_thickness_scale(plt, series[:markerstrokewidth]), extrakw... ) push!(handles, handle) @@ -624,7 +624,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex], gridsize = series[:bins], - linewidths = py_dpi_scale(plt, series[:linewidth]), + linewidths = py_thickness_scale(plt, series[:linewidth]), edgecolors = py_linecolor(series), cmap = py_fillcolormap(series), # applies to the pcolorfast object extrakw... @@ -655,7 +655,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) handle = ax[:contour](x, y, z, levelargs...; label = series[:label], zorder = series[:series_plotindex], - linewidths = py_dpi_scale(plt, series[:linewidth]), + linewidths = py_thickness_scale(plt, series[:linewidth]), linestyles = py_linestyle(st, series[:linestyle]), extrakw... ) @@ -697,7 +697,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], rstride = series[:stride][1], cstride = series[:stride][2], - linewidth = py_dpi_scale(plt, series[:linewidth]), + linewidth = py_thickness_scale(plt, series[:linewidth]), edgecolor = py_linecolor(series), extrakw... ) @@ -728,7 +728,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) label = series[:label], zorder = series[:series_plotindex], cmap = py_fillcolormap(series), - linewidth = py_dpi_scale(plt, series[:linewidth]), + linewidth = py_thickness_scale(plt, series[:linewidth]), edgecolor = py_linecolor(series), extrakw... ) @@ -796,7 +796,7 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) zorder = series[:series_plotindex], edgecolor = py_color(get_linecolor(series, i), get_linealpha(series, i)), facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)), - linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linewidth = py_thickness_scale(plt, get_linewidth(series, i)), linestyle = py_linestyle(st, get_linestyle(series, i)), fill = true ) @@ -955,8 +955,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) w, h = plt[:size] fig = plt.o fig[:clear]() - dpi = plt[:thickness_scaling] * plt[:dpi] - fig[:set_size_inches](w/DPI/plt[:thickness_scaling], h/DPI/plt[:thickness_scaling], forward = true) + dpi = plt[:dpi] + fig[:set_size_inches](w/DPI, h/DPI, forward = true) fig[set_facecolor_sym](py_color(plt[:background_color_outside])) fig[:set_dpi](plt[:dpi]) @@ -996,7 +996,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) :title end ax[func][:set_text](sp[:title]) - ax[func][:set_fontsize](py_dpi_scale(plt, sp[:titlefontsize])) + ax[func][:set_fontsize](py_thickness_scale(plt, sp[:titlefontsize])) ax[func][:set_family](sp[:titlefontfamily]) ax[func][:set_color](py_color(sp[:titlefontcolor])) # ax[:set_title](sp[:title], loc = loc) @@ -1036,9 +1036,9 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) fig = plt.o cbax = fig[:add_axes]([0.8,0.1,0.03,0.8], label = string(gensym())) cb = fig[:colorbar](handle; cax = cbax, kw...) - cb[:set_label](sp[:colorbar_title],size=py_dpi_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor])) + cb[:set_label](sp[:colorbar_title],size=py_thickness_scale(plt, sp[:yaxis][:guidefontsize]),family=sp[:yaxis][:guidefontfamily], color = py_color(sp[:yaxis][:guidefontcolor])) for lab in cb[:ax][:yaxis][:get_ticklabels]() - lab[:set_fontsize](py_dpi_scale(plt, sp[:yaxis][:tickfontsize])) + lab[:set_fontsize](py_thickness_scale(plt, sp[:yaxis][:tickfontsize])) lab[:set_family](sp[:yaxis][:tickfontfamily]) lab[:set_color](py_color(sp[:yaxis][:tickfontcolor])) end @@ -1048,12 +1048,14 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) # framestyle if !ispolar(sp) && !is3d(sp) + ax[:spines]["left"][:set_linewidth](py_thickness_scale(plt, 1)) + ax[:spines]["bottom"][:set_linewidth](py_thickness_scale(plt, 1)) if sp[:framestyle] == :semi intensity = 0.5 ax[:spines]["right"][:set_alpha](intensity) ax[:spines]["top"][:set_alpha](intensity) - ax[:spines]["right"][:set_linewidth](intensity) - ax[:spines]["top"][:set_linewidth](intensity) + ax[:spines]["right"][:set_linewidth](py_thickness_scale(plt, intensity)) + ax[:spines]["top"][:set_linewidth](py_thickness_scale(plt, intensity)) elseif sp[:framestyle] in (:axes, :origin) ax[:spines]["right"][:set_visible](false) ax[:spines]["top"][:set_visible](false) @@ -1066,8 +1068,8 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) spine[:set_visible](false) end if sp[:framestyle] == :zerolines - ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = 0.75) - ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = 0.75) + ax[:axhline](y = 0, color = py_color(sp[:xaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75)) + ax[:axvline](x = 0, color = py_color(sp[:yaxis][:foreground_color_axis]), lw = py_thickness_scale(plt, 0.75)) end end end @@ -1100,10 +1102,10 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) if get(axis.d, :flip, false) ax[Symbol("invert_", letter, "axis")]() end - pyaxis[:label][:set_fontsize](py_dpi_scale(plt, axis[:guidefontsize])) + pyaxis[:label][:set_fontsize](py_thickness_scale(plt, axis[:guidefontsize])) pyaxis[:label][:set_family](axis[:guidefontfamily]) for lab in ax[Symbol("get_", letter, "ticklabels")]() - lab[:set_fontsize](py_dpi_scale(plt, axis[:tickfontsize])) + lab[:set_fontsize](py_thickness_scale(plt, axis[:tickfontsize])) lab[:set_family](axis[:tickfontfamily]) lab[:set_rotation](axis[:rotation]) end @@ -1112,7 +1114,7 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) pyaxis[:grid](true, color = fgcolor, linestyle = py_linestyle(:line, axis[:gridstyle]), - linewidth = axis[:gridlinewidth], + linewidth = py_thickness_scale(plt, axis[:gridlinewidth]), alpha = axis[:gridalpha]) ax[:set_axisbelow](true) else @@ -1209,7 +1211,7 @@ function _update_min_padding!(sp::Subplot{PyPlotBackend}) rightpad += sp[:right_margin] bottompad += sp[:bottom_margin] - dpi_factor = sp.plt[:thickness_scaling] * Plots.DPI / sp.plt[:dpi] + dpi_factor = Plots.DPI / sp.plt[:dpi] sp.minpad = Tuple(dpi_factor .* [leftpad, toppad, rightpad, bottompad]) end @@ -1232,7 +1234,7 @@ function py_add_annotations(sp::Subplot{PyPlotBackend}, x, y, val::PlotText) horizontalalignment = val.font.halign == :hcenter ? "center" : string(val.font.halign), verticalalignment = val.font.valign == :vcenter ? "center" : string(val.font.valign), rotation = val.font.rotation * 180 / π, - size = py_dpi_scale(sp.plt, val.font.pointsize), + size = py_thickness_scale(sp.plt, val.font.pointsize), zorder = 999 ) end @@ -1263,13 +1265,13 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) pypatches[:Patch]( edgecolor = py_color(get_linecolor(series), get_linealpha(series)), facecolor = py_color(get_fillcolor(series), get_fillalpha(series)), - linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)), linestyle = py_linestyle(series[:seriestype], get_linestyle(series)) ) elseif series[:seriestype] in (:path, :straightline) PyPlot.plt[:Line2D]((0,1),(0,0), color = py_color(get_linecolor(series), get_linealpha(series)), - linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linewidth = py_thickness_scale(plt, clamp(get_linewidth(series), 0, 5)), linestyle = py_linestyle(:path, get_linestyle(series)), marker = py_marker(series[:markershape]), markeredgecolor = py_color(get_markerstrokecolor(series), get_markerstrokealpha(series)), @@ -1288,10 +1290,11 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) labels, loc = get(_pyplot_legend_pos, leg, "best"), scatterpoints = 1, - fontsize = py_dpi_scale(plt, sp[:legendfontsize]), + fontsize = py_thickness_scale(plt, sp[:legendfontsize]), facecolor = py_color(sp[:background_color_legend]), edgecolor = py_color(sp[:foreground_color_legend]), framealpha = alpha(plot_color(sp[:background_color_legend])), + linewidth = py_thickness_scale(plt, 0.75), ) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) @@ -1360,7 +1363,7 @@ for (mime, fmt) in _pyplot_mimeformats # figsize = map(px2inch, plt[:size]), facecolor = fig[:get_facecolor](), edgecolor = "none", - dpi = plt[:dpi] * plt[:thickness_scaling] + dpi = plt[:dpi] ) end end From 789cf1d66b5210d2339bfc42705a84bf4b4027ac Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Wed, 25 Jul 2018 23:39:55 +0200 Subject: [PATCH 719/720] fix legend frame --- src/backends/pyplot.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index 1adff445..92f33fd5 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -1294,8 +1294,9 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) facecolor = py_color(sp[:background_color_legend]), edgecolor = py_color(sp[:foreground_color_legend]), framealpha = alpha(plot_color(sp[:background_color_legend])), - linewidth = py_thickness_scale(plt, 0.75), ) + frame = leg[:get_frame]() + frame[:set_linewidth](py_thickness_scale(plt, 1)) leg[:set_zorder](1000) sp[:legendtitle] != nothing && leg[:set_title](sp[:legendtitle]) From 72c4962e97bf663c145f4a55a703c3ee6daadaa5 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Thu, 26 Jul 2018 16:43:05 +0200 Subject: [PATCH 720/720] prepare backports release --- NEWS.md | 3 +++ test/imgcomp.jl | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 197ce33d..930df8b0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,9 @@ ## (current master) - All new development should target Julia 0.7! +## 0.17.4 +- fix thickness_scaling for pyplot + ## 0.17.3 - Log-scale heatmap edge computation - Fix size and dpi for GR and PyPlot diff --git a/test/imgcomp.jl b/test/imgcomp.jl index 625d6d77..7ad523fd 100644 --- a/test/imgcomp.jl +++ b/test/imgcomp.jl @@ -23,7 +23,7 @@ default(size=(500,300)) # TODO: use julia's Condition type and the wait() and notify() functions to initialize a Window, then wait() on a condition that # is referenced in a button press callback (the button clicked callback will call notify() on that condition) -const _current_plots_version = v"0.17.3" +const _current_plots_version = v"0.17.4" function image_comparison_tests(pkg::Symbol, idx::Int; debug = false, popup = isinteractive(), sigma = [1,1], eps = 1e-2)