Fix vector attributes to bar plots
This commit is contained in:
parent
31d3bf3e06
commit
dbb3942047
@ -1232,6 +1232,23 @@ const _examples = PlotExample[
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
PlotExample( # 56
|
||||||
|
"Bar plot customizations",
|
||||||
|
"""
|
||||||
|
Width of bars may be specified as `bar_width`.
|
||||||
|
The bars' baseline may be specified as `fillto`.
|
||||||
|
Each may be scalar, or a vector spcifying one value per bar.
|
||||||
|
""",
|
||||||
|
[:(
|
||||||
|
begin
|
||||||
|
plot(bar([-1,0,2,3], [1,3,6,2],
|
||||||
|
fill_z = 4:-1:1, alpha = [1, 0.2, 0.8, 0.5], label = "", bar_width = 1:4),
|
||||||
|
bar(rand(5), bar_width=1.2, alpha=0.8,
|
||||||
|
color=[:lightsalmon, :tomato, :crimson, :firebrick, :darkred],
|
||||||
|
fillto=0:-0.1:-0.4, label="reds"))
|
||||||
|
end
|
||||||
|
)],
|
||||||
|
),
|
||||||
]
|
]
|
||||||
|
|
||||||
# Some constants for PlotDocs and PlotReferenceImages
|
# Some constants for PlotDocs and PlotReferenceImages
|
||||||
|
|||||||
@ -508,6 +508,18 @@ end
|
|||||||
primary := true
|
primary := true
|
||||||
x := xseg.pts
|
x := xseg.pts
|
||||||
y := yseg.pts
|
y := yseg.pts
|
||||||
|
# expand attributes to match indices in new series data
|
||||||
|
for k in _segmenting_vector_attributes ∪ _segmenting_array_attributes
|
||||||
|
v = get(plotattributes, k, nothing)
|
||||||
|
if v isa AVec
|
||||||
|
if eachindex(v) != eachindex(y)
|
||||||
|
@warn "Indices $(eachindex(v)) of attribute `$k` do not match data indices $(eachindex(y))."
|
||||||
|
end
|
||||||
|
# Each segment is 6 elements long, including the NaN separator.
|
||||||
|
# There is no trailing NaN, so the last repetition is dropped.
|
||||||
|
plotattributes[k] = @view repeat(v; inner=6)[1:end-1]
|
||||||
|
end
|
||||||
|
end
|
||||||
()
|
()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
16
src/utils.jl
16
src/utils.jl
@ -103,7 +103,10 @@ function series_segments(series::Series, seriestype::Symbol = :path; check = fal
|
|||||||
|
|
||||||
segments = if has_attribute_segments(series)
|
segments = if has_attribute_segments(series)
|
||||||
Iterators.flatten(map(nan_segments) do r
|
Iterators.flatten(map(nan_segments) do r
|
||||||
if seriestype in (:scatter, :scatter3d)
|
if seriestype == :shape
|
||||||
|
warn_on_inconsistent_shape_attr(series, x, y, z, r)
|
||||||
|
(SeriesSegment(r, first(r)),)
|
||||||
|
elseif seriestype in (:scatter, :scatter3d)
|
||||||
(SeriesSegment(i:i, i) for i in r)
|
(SeriesSegment(i:i, i) for i in r)
|
||||||
else
|
else
|
||||||
(SeriesSegment(i:(i + 1), i) for i in first(r):(last(r) - 1))
|
(SeriesSegment(i:(i + 1), i) for i in first(r):(last(r) - 1))
|
||||||
@ -140,6 +143,16 @@ function warn_on_attr_dim_mismatch(series, x, y, z, segments)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function warn_on_inconsistent_shape_attr(series, x, y, z, r)
|
||||||
|
for attr in _segmenting_vector_attributes
|
||||||
|
v = get(series, attr, nothing)
|
||||||
|
if v isa AVec && length(unique(v[r])) > 1
|
||||||
|
@warn "Different values of `$attr` specified for different shape vertices. Only first one will be used."
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# helpers to figure out if there are NaN values in a list of array types
|
# helpers to figure out if there are NaN values in a list of array types
|
||||||
anynan(i::Int, args::Tuple) = any(a -> try
|
anynan(i::Int, args::Tuple) = any(a -> try
|
||||||
isnan(_cycle(a, i))
|
isnan(_cycle(a, i))
|
||||||
@ -573,7 +586,6 @@ const _segmenting_array_attributes = :line_z, :fill_z, :marker_z
|
|||||||
function has_attribute_segments(series::Series)
|
function has_attribute_segments(series::Series)
|
||||||
# we want to check if a series needs to be split into segments just because
|
# we want to check if a series needs to be split into segments just because
|
||||||
# of its attributes
|
# of its attributes
|
||||||
series[:seriestype] == :shape && return false
|
|
||||||
# check relevant attributes if they have multiple inputs
|
# check relevant attributes if they have multiple inputs
|
||||||
return any(
|
return any(
|
||||||
series[attr] isa AbstractVector && length(series[attr]) > 1 for
|
series[attr] isa AbstractVector && length(series[attr]) > 1 for
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user