Merge branch 'master' into segments-legendgroup-fix

This commit is contained in:
Daniel Schwabeneder 2018-05-06 09:37:08 +02:00 committed by GitHub
commit ee78385b4c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 85 additions and 99 deletions

View File

@ -1528,11 +1528,11 @@ 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(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

View File

@ -353,25 +353,18 @@ 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
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
@ -1046,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

View File

@ -173,14 +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))
if d[:markerstrokealpha] != nothing
a_stroke = _cycle(d[:markerstrokealpha], i)
end
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)))
"""
mark = $(get(_pgfplots_markers, shape, "*")),
mark size = $(0.5 * _cycle(d[:markersize], i)),
@ -222,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

View File

@ -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
@ -491,7 +491,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
@ -517,7 +517,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
@ -633,31 +633,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]),
:size => 2 * _cycle(series[:markersize], inds),
:color => rgba_string.(plot_color.(get_markercolor.(series, inds), get_markeralpha.(series, inds))),
:line => KW(
:color => _cycle(rgba_string.(series[:markerstrokecolor]),eachindex(series[:x])),
:width => series[:markerstrokewidth],
:color => rgba_string.(plot_color.(get_markerstrokecolor.(series, inds), get_markerstrokealpha.(series, inds))),
:width => _cycle(series[:markerstrokewidth], inds),
),
)
# 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)
@ -675,13 +661,14 @@ 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],
: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))
)
@ -689,7 +676,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]]),
@ -710,9 +697,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, d_base, :marker))
end
d_outs
end
@ -730,7 +719,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
@ -768,30 +757,15 @@ function plotly_series_segments(series::Series, d_base::KW, x, y, z)
# add "marker"
if hasmarker
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(series[:markercolor]),
:size => 2 * _cycle(series[:markersize], i),
:color => rgba_string(plot_color(get_markercolor(series, i), get_markeralpha(series, i))),
:line => KW(
:color => _cycle(rgba_string.(series[:markerstrokecolor]), eachindex(rng)),
:width => series[:markerstrokewidth],
:color => rgba_string(plot_color(get_markerstrokecolor(series, i), get_markerstrokealpha(series, i))),
:width => _cycle(series[:markerstrokewidth], i),
),
)
# 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"
@ -850,6 +824,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

View File

@ -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

View File

@ -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

View File

@ -195,9 +195,13 @@ 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}[]
segs = UnitRange{Int}[]
args = is3d(series) ? (x, y, z) : (x, y)
for seg in iter_segments(args...)
push!(segs, seg)
@ -656,6 +660,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
@ -666,7 +695,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
# ---------------------------------------------------------------