From f89b1ba303fd4f40a392a023f3e3fcb3a05181c0 Mon Sep 17 00:00:00 2001 From: Daniel Schwabeneder Date: Mon, 2 Apr 2018 00:41:13 +0200 Subject: [PATCH] implement vector arguments for GR and PyPlot --- src/args.jl | 16 +++--- src/backends/gr.jl | 65 +++++++++++---------- src/backends/pyplot.jl | 127 +++++++++++++++++++++-------------------- src/utils.jl | 17 ++++++ 4 files changed, 123 insertions(+), 102 deletions(-) diff --git a/src/args.jl b/src/args.jl index 68354760..a1df9264 100644 --- a/src/args.jl +++ b/src/args.jl @@ -1450,18 +1450,18 @@ end # converts a symbol or string into a colorant (Colors.RGB), and assigns a color automatically -function getSeriesRGBColor(c, α, sp::Subplot, n::Int) +function getSeriesRGBColor(c, sp::Subplot, n::Int) if c == :auto c = autopick(sp[:color_palette], n) elseif isa(c, Int) c = autopick(sp[:color_palette], c) end - plot_color(c, α) + plot_color(c) end function ensure_gradient!(d::KW, csym::Symbol, asym::Symbol) if !isa(d[csym], ColorGradient) - d[csym] = cgrad(alpha = d[asym]) + d[csym] = typeof(d[asym]) <: AbstractVector ? cgrad() : cgrad(alpha = d[asym]) end end @@ -1508,21 +1508,21 @@ function _add_defaults!(d::KW, plt::Plot, sp::Subplot, commandIndex::Int) end # update series color - d[:seriescolor] = getSeriesRGBColor(d[:seriescolor], d[:seriesalpha], sp, plotIndex) + d[:seriescolor] = getSeriesRGBColor.(d[:seriescolor], sp, plotIndex) # update other colors for s in (:line, :marker, :fill) csym, asym = Symbol(s,:color), Symbol(s,:alpha) d[csym] = if d[csym] == :auto - plot_color(if has_black_border_for_default(d[:seriestype]) && s == :line + plot_color.(if has_black_border_for_default(d[:seriestype]) && s == :line sp[:foreground_color_subplot] else d[:seriescolor] - end, d[asym]) + end) elseif d[csym] == :match - plot_color(d[:seriescolor], d[asym]) + plot_color.(d[:seriescolor]) else - getSeriesRGBColor(d[csym], d[asym], sp, plotIndex) + getSeriesRGBColor.(d[csym], sp, plotIndex) end end diff --git a/src/backends/gr.jl b/src/backends/gr.jl index e60ea894..f35866c9 100644 --- a/src/backends/gr.jl +++ b/src/backends/gr.jl @@ -135,7 +135,7 @@ const gr_font_family = Dict( # -------------------------------------------------------------------------------------- function gr_getcolorind(c) - GR.settransparency(float(alpha(c))) + gr_set_transparency(float(alpha(c))) convert(Int, GR.inqcolorfromrgb(red(c), green(c), blue(c))) end @@ -143,6 +143,7 @@ gr_set_linecolor(c) = GR.setlinecolorind(gr_getcolorind(_cycle(c,1))) gr_set_fillcolor(c) = GR.setfillcolorind(gr_getcolorind(_cycle(c,1))) gr_set_markercolor(c) = GR.setmarkercolorind(gr_getcolorind(_cycle(c,1))) gr_set_textcolor(c) = GR.settextcolorind(gr_getcolorind(_cycle(c,1))) +gr_set_transparency(α::Real) = GR.settransparency(clamp(α, 0, 1)) # -------------------------------------------------------------------------------------- @@ -230,7 +231,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw angular grid if xaxis[:grid] gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) for i in 1:length(α) GR.polyline([sinf[i], 0], [cosf[i], 0]) end @@ -239,7 +240,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) #draw radial grid if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) for i in 1:length(rtick_values) r = (rtick_values[i] - rmin) / (rmax - rmin) if r <= 1.0 && r >= 0.0 @@ -250,7 +251,7 @@ function gr_polaraxes(rmin::Real, rmax::Real, sp::Subplot) end #prepare to draw ticks - GR.settransparency(1) + gr_set_transparency(1) GR.setlinecolorind(90) GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) @@ -319,9 +320,6 @@ function normalize_zvals(zv::AVec, clims::NTuple{2, <:Real}) end end -gr_alpha(α::Void) = 1 -gr_alpha(α::Real) = α - # --------------------------------------------------------- # draw ONE Shape @@ -369,7 +367,7 @@ function gr_draw_markers(series::Series, x, y, msize, mz) # pick a color from the pre-loaded gradient ci = round(Int, 1000 + _cycle(mz, i) * 255) cfuncind(ci) - GR.settransparency(_gr_gradient_alpha[ci-999]) + gr_set_transparency(_gr_gradient_alpha[ci-999]) end # don't draw filled area if marker shape is 1D if !(shape in (:hline, :vline, :+, :x)) @@ -794,21 +792,21 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if xaxis[:grid] gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) end if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) end if zaxis[:grid] gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid]) - GR.settransparency(zaxis[:gridalpha]) + gr_set_transparency(zaxis[:gridalpha]) GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) end gr_set_line(1, :solid, xaxis[:foreground_color_axis]) - GR.settransparency(1) + gr_set_transparency(1) GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) @@ -831,15 +829,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # gr_set_linecolor(sp[:foreground_color_grid]) # GR.grid(xtick, ytick, 0, 0, majorx, majory) gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) gr_polyline(coords(xgrid_segs)...) end if yaxis[:grid] gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) gr_polyline(coords(ygrid_segs)...) end - GR.settransparency(1.0) + gr_set_transparency(1.0) # axis lines if xaxis[:showaxis] @@ -858,7 +856,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if xaxis[:showaxis] if sp[:framestyle] in (:zerolines, :grid) gr_set_line(1, :solid, xaxis[:foreground_color_grid]) - GR.settransparency(xaxis[:gridalpha]) + gr_set_transparency(xaxis[:gridalpha]) else gr_set_line(1, :solid, xaxis[:foreground_color_axis]) end @@ -868,7 +866,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if yaxis[:showaxis] if sp[:framestyle] in (:zerolines, :grid) gr_set_line(1, :solid, yaxis[:foreground_color_grid]) - GR.settransparency(yaxis[:gridalpha]) + gr_set_transparency(yaxis[:gridalpha]) else gr_set_line(1, :solid, yaxis[:foreground_color_axis]) end @@ -920,10 +918,10 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) intensity = sp[:framestyle] == :semi ? 0.5 : 1.0 if sp[:framestyle] in (:box, :semi) gr_set_line(intensity, :solid, xaxis[:foreground_color_border]) - GR.settransparency(intensity) + gr_set_transparency(intensity) gr_polyline(coords(xborder_segs)...) gr_set_line(intensity, :solid, yaxis[:foreground_color_border]) - GR.settransparency(intensity) + gr_set_transparency(intensity) gr_polyline(coords(yborder_segs)...) end end @@ -1030,7 +1028,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) gr_set_fillcolor(get_fillcolor(series, i)) fx = _cycle(x, vcat(rng, reverse(rng))) fy = vcat(_cycle(fr_from,rng), _cycle(fr_to,reverse(rng))) - series[:fillalpha] != nothing && GR.settransparency(series[:fillalpha]) + gr_set_transparency(get_fillalpha(series, i)) GR.fillarea(fx, fy) end end @@ -1038,7 +1036,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the line(s) if st in (:path, :straightline) for (i, rng) in enumerate(segments) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha]) + gr_set_transparency(get_linealpha(series, i)) arrowside = isa(series[:arrow], Arrow) ? series[:arrow].side : :none gr_polyline(x[rng], y[rng]; arrowside = arrowside) end @@ -1064,8 +1063,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if series[:fillrange] != nothing GR.surface(x, y, z, GR.OPTION_CELL_ARRAY) else - GR.setlinetype(gr_linetype[series[:linestyle]]) - GR.setlinewidth(max(0, series[:linewidth] / (sum(gr_plot_size) * 0.001))) + GR.setlinetype(gr_linetype[get_linestyle(series)]) + GR.setlinewidth(max(0, get_linewidth(series) / (sum(gr_plot_size) * 0.001))) if plot_color(series[:linecolor]) == [plot_color(:black)] GR.contour(x, y, h, z, 0 + (series[:contour_labels] == true ? 1 : 0)) else @@ -1117,7 +1116,8 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) lz = series[:line_z] segments = iter_segments(series) for (i, rng) in enumerate(segments) - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series, i)) #, series[:linealpha]) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) #, series[:linealpha]) + gr_set_transparency(get_linealpha(series, i)) GR.polyline3d(x[rng], y[rng], z[rng]) end end @@ -1189,10 +1189,12 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the interior gr_set_fill(get_fillcolor(series, i)) + gr_set_transparency(get_fillalpha(series, i)) GR.fillarea(xseg, yseg) # draw the shapes - gr_set_line(series[:linewidth], :solid, get_linecolor(series, i)) + gr_set_line(get_linewidth(series, i), get_linestyle(series, i), get_linecolor(series, i)) + gr_set_transparency(get_linealpha(series, i)) GR.polyline(xseg, yseg) end end @@ -1224,7 +1226,7 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) # draw the colorbar if cmap && st != :contour # special colorbar with steps is drawn for contours gr_set_line(1, :solid, yaxis[:foreground_color_axis]) - GR.settransparency(1) + gr_set_transparency(1) gr_colorbar(sp, clims) end @@ -1271,14 +1273,14 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) if sp[:legendtitle] != nothing GR.settextalign(GR.TEXT_HALIGN_CENTER, GR.TEXT_VALIGN_HALF) gr_set_textcolor(sp[:legendfontcolor]) - GR.settransparency(1) + gr_set_transparency(1) gr_text(xpos - 0.03 + 0.5*w, ypos, string(sp[:legendtitle])) ypos -= dy end for series in series_list(sp) should_add_to_legend(series) || continue st = series[:seriestype] - gr_set_line(series[:linewidth], series[:linestyle], get_linecolor(series)) #, series[:linealpha]) + gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series)) #, series[:linealpha]) if (st == :shape || series[:fillrange] != nothing) && series[:ribbon] == nothing gr_set_fill(get_fillcolor(series)) #, series[:fillalpha]) @@ -1286,14 +1288,15 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas) b, t = ypos-0.4dy, ypos+0.4dy x = [l, r, r, l, l] y = [b, b, t, t, b] - GR.settransparency(gr_alpha(series[:fillalpha])) + gr_set_transparency(get_fillalpha(series)) gr_polyline(x, y, GR.fillarea) - GR.settransparency(gr_alpha(series[:linealpha])) + gr_set_transparency(get_linealpha(series)) + gr_set_line(get_linewidth(series), get_linestyle(series), get_linecolor(series)) st == :shape && gr_polyline(x, y) end if st in (:path, :straightline) - GR.settransparency(gr_alpha(series[:linealpha])) + gr_set_transparency(get_linealpha(series)) if series[:fillrange] == nothing || series[:ribbon] != nothing GR.polyline([xpos - 0.07, xpos - 0.01], [ypos, ypos]) else diff --git a/src/backends/pyplot.jl b/src/backends/pyplot.jl index fe67ac7e..21c7b773 100644 --- a/src/backends/pyplot.jl +++ b/src/backends/pyplot.jl @@ -136,6 +136,7 @@ py_color(s) = py_color(parse(Colorant, string(s))) py_color(c::Colorant) = (red(c), green(c), blue(c), alpha(c)) py_color(cs::AVec) = map(py_color, cs) py_color(grad::ColorGradient) = py_color(grad.colors) +py_color(c::Colorant, α) = py_color(plot_color(c, α)) function py_colormap(grad::ColorGradient) pyvals = [(z, py_color(grad[z])) for z in grad.values] @@ -492,60 +493,49 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # line plot if st in (:path, :path3d, :steppre, :steppost, :straightline) - if series[:linewidth] > 0 - if series[:line_z] == nothing - handle = ax[:plot](xyargs...; - label = series[:label], - zorder = series[:series_plotindex], - color = py_linecolor(series), - linewidth = py_dpi_scale(plt, series[:linewidth]), - linestyle = py_linestyle(st, series[:linestyle]), - solid_capstyle = "round", - drawstyle = py_stepstyle(st) - )[1] - push!(handles, handle) - - else + if maximum(series[:linewidth]) > 0 + segments = iter_segments(series) + if length(segments) > 1 && (any(typeof(series[attr]) <: AbstractVector for attr in (:fillcolor, :fillalpha)) || series[:fill_z] != nothing) # multicolored line segments - n = length(x) - 1 + n = length(segments) # segments = Array(Any,n) segments = [] kw = KW( :label => series[:label], :zorder => plt.n, :cmap => py_linecolormap(series), - :linewidth => py_dpi_scale(plt, series[:linewidth]), - :linestyle => py_linestyle(st, series[:linestyle]), + :linewidths => py_dpi_scale(plt, get_linewidth.(series, 1:n)), + :linestyles => py_linestyle(st, get_linestyle(series, 1:n)), :norm => pycolors["Normalize"](; extrakw...) ) lz = _cycle(series[:line_z], 1:n) handle = if is3d(st) - for rng in iter_segments(x, y, z) - length(rng) < 2 && continue - for i in rng[1:end-1] - push!(segments, [(_cycle(x,i),_cycle(y,i),_cycle(z,i)), - (_cycle(x,i+1),_cycle(y,i+1),_cycle(z,i+1))]) - end - end - - lc = pyart3d["Line3DCollection"](segments; kw...) + line_segments = [[(x[j], y[j], z[j]) for j in rng] for rng in segments] + lc = pyart3d["Line3DCollection"](line_segments; kw...) lc[:set_array](lz) ax[:add_collection3d](lc, zs=z) #, zdir='y') lc else - for rng in iter_segments(x, y) - length(rng) < 2 && continue - for i in rng[1:end-1] - push!(segments, [(_cycle(x,i),_cycle(y,i)), (_cycle(x,i+1),_cycle(y,i+1))]) - end - end - - lc = pycollections["LineCollection"](segments; kw...) + line_segments = [[(x[j], y[j]) for j in rng] for rng in segments] + lc = pycollections["LineCollection"](line_segments; kw...) lc[:set_array](lz) ax[:add_collection](lc) lc end push!(handles, handle) + else + for (i, rng) in enumerate(iter_segments(series)) + handle = ax[:plot]((arg[rng] for arg in xyargs)...; + label = i == 1 ? series[:label] : "", + zorder = series[:series_plotindex], + color = py_color(get_linecolor(series, i), get_linealpha(series, i)), + linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linestyle = py_linestyle(st, get_linestyle(series, i)), + solid_capstyle = "round", + drawstyle = py_stepstyle(st) + )[1] + push!(handles, handle) + end end a = series[:arrow] @@ -559,8 +549,8 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) :shrinkB => 0, :edgecolor => py_linecolor(series), :facecolor => py_linecolor(series), - :linewidth => py_dpi_scale(plt, series[:linewidth]), - :linestyle => py_linestyle(st, series[:linestyle]), + :linewidth => py_dpi_scale(plt, get_linewidth(series)), + :linestyle => py_linestyle(st, get_linestyle(series)), ) add_arrows(x, y) do xyprev, xy ax[:annotate]("", @@ -794,16 +784,17 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) if st == :shape handle = [] - for (i,rng) in enumerate(iter_segments(x, y)) + for (i, rng) in enumerate(iter_segments(series)) if length(rng) > 1 path = pypath["Path"](hcat(x[rng], y[rng])) patches = pypatches["PathPatch"]( path; label = series[:label], zorder = series[:series_plotindex], - edgecolor = py_color(_cycle(series[:linecolor], i)), - facecolor = py_color(_cycle(series[:fillcolor], i)), - linewidth = py_dpi_scale(plt, series[:linewidth]), + edgecolor = py_color(get_linecolor(series, i), get_linealpha(series, i)), + facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)), + linewidth = py_dpi_scale(plt, get_linewidth(series, i)), + linestyle = py_linestyle(st, get_linestyle(series, i)), fill = true ) push!(handle, ax[:add_patch](patches)) @@ -835,24 +826,26 @@ function py_add_series(plt::Plot{PyPlotBackend}, series::Series) # handle area filling fillrange = series[:fillrange] if fillrange != nothing && st != :contour - f, dim1, dim2 = if isvertical(series) - :fill_between, x, y - else - :fill_betweenx, y, x - end - n = length(dim1) - args = if typeof(fillrange) <: Union{Real, AVec} - dim1, expand_data(fillrange, n), dim2 - elseif is_2tuple(fillrange) - dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) - end + for (i, rng) in enumerate(iter_segments(series)) + f, dim1, dim2 = if isvertical(series) + :fill_between, x[rng], y[rng] + else + :fill_betweenx, y[rng], x[rng] + end + n = length(dim1) + args = if typeof(fillrange) <: Union{Real, AVec} + dim1, expand_data(fillrange, n), dim2 + elseif is_2tuple(fillrange) + dim1, expand_data(fillrange[1], n), expand_data(fillrange[2], n) + end - handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); - zorder = series[:series_plotindex], - facecolor = py_fillcolor(series), - linewidths = 0 - ) - push!(handles, handle) + handle = ax[f](args..., trues(n), false, py_fillstepstyle(st); + zorder = series[:series_plotindex], + facecolor = py_color(get_fillcolor(series, i), get_fillalpha(series, i)), + linewidths = 0 + ) + push!(handles, handle) + end end # this is all we need to add the series_annotations text @@ -1020,6 +1013,13 @@ function _before_layout_calcs(plt::Plot{PyPlotBackend}) kw[:ticks] = locator kw[:format] = formatter kw[:boundaries] = vcat(0, kw[:values] + 0.5) + elseif any(colorbar_series[attr] != nothing for attr in (:line_z, :fill_z)) + cmin, cmax = get_clims(sp) + norm = pycolors[:Normalize](vmin = cmin, vmax = cmax) + f = colorbar_series[:line_z] != nothing ? py_linecolormap : py_fillcolormap + cmap = pycmap[:ScalarMappable](norm = norm, cmap = f(colorbar_series)) + cmap[:set_array]([]) + handle = cmap end # create and store the colorbar object (handle) and the axis that it is drawn on. @@ -1250,15 +1250,16 @@ function py_add_legend(plt::Plot, sp::Subplot, ax) # add a line/marker and a label push!(handles, if series[:seriestype] == :shape || series[:fillrange] != nothing pypatches[:Patch]( - edgecolor = py_color(_cycle(series[:linecolor],1)), - facecolor = py_color(_cycle(series[:fillcolor],1)), - linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), + edgecolor = py_color(get_linecolor(series), get_linealpha(series)), + facecolor = py_color(get_fillcolor(series), get_fillalpha(series)), + linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linestyle = py_linestyle(series[:seriestype], get_linestyle(series)) ) elseif series[:seriestype] in (:path, :straightline) PyPlot.plt[:Line2D]((0,1),(0,0), - color = py_color(_cycle(series[:linecolor],1)), - linewidth = py_dpi_scale(plt, clamp(series[:linewidth], 0, 5)), - linestyle = py_linestyle(:path,series[:linestyle]), + color = py_color(get_linecolor(series), get_linealpha(series)), + linewidth = py_dpi_scale(plt, clamp(get_linewidth(series), 0, 5)), + linestyles = py_linestyle(:path, get_linestyle(series)), marker = py_marker(series[:markershape]), markeredgecolor = py_markerstrokecolor(series), markerfacecolor = series[:marker_z] == nothing ? py_markercolor(series) : py_color(series[:markercolor][0.5]) diff --git a/src/utils.jl b/src/utils.jl index 252f9aed..e2232936 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -628,6 +628,18 @@ function get_linecolor(series::Series, i::Int = 1) end end +function get_linealpha(series::Series, i::Int = 1) + _cycle(series[:linealpha], i) +end + +function get_linewidth(series::Series, i::Int = 1) + _cycle(series[:linewidth], i) +end + +function get_linestyle(series::Series, i::Int = 1) + _cycle(series[:linestyle], i) +end + function get_fillcolor(series::Series, i::Int = 1) fc = series[:fillcolor] fz = series[:fill_z] @@ -645,6 +657,10 @@ function get_fillcolor(series::Series, i::Int = 1) end end +function get_fillalpha(series::Series, i::Int = 1) + _cycle(series[:fillalpha], i) +end + function has_attribute_segments(series::Series) # we want to check if a series needs to be split into segments just because # of its attributes @@ -653,6 +669,7 @@ function has_attribute_segments(series::Series) # SegmentsIterator is used series[letter] != nothing && NaN in series[letter] && return false end + series[:seriestype] == :shape && return false # ... else we check relevant attributes if they have multiple inputs return any((typeof(series[attr]) <: AbstractVector && length(series[attr]) > 1) for attr in [:seriescolor, :seriesalpha, :linecolor, :linealpha, :linewidth, :fillcolor, :fillalpha]) || any(typeof(series[attr]) <: AbstractArray{<:Real} for attr in (:line_z, :fill_z)) end