From fd37a9c660252361cd9396edbe7639ea5500836b Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Fri, 27 Apr 2018 17:44:20 +0200 Subject: [PATCH 01/65] 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 02/65] 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 03/65] 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 04/65] 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 05/65] 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 06/65] 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 07/65] 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 08/65] 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 09/65] 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 10/65] 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 11/65] 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 12/65] 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 13/65] 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 14/65] 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 15/65] 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 16/65] 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 17/65] 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 18/65] 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 19/65] 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 20/65] 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 21/65] 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 22/65] 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 23/65] 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 24/65] 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 25/65] 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 26/65] 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 27/65] 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 28/65] 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 29/65] 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 30/65] 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 31/65] 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 32/65] 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 33/65] 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 34/65] 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 35/65] 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 36/65] 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 37/65] 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 38/65] 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 39/65] 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 40/65] 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 41/65] 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 42/65] 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 43/65] 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 44/65] 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 45/65] 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 46/65] 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 47/65] 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 48/65] 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 49/65] 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 50/65] 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 51/65] 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 52/65] 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 53/65] 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 54/65] 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 55/65] 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 56/65] 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 57/65] 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 58/65] 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 59/65] 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 60/65] 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 61/65] 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 62/65] 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 63/65] 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 64/65] 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 65/65] 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)