# Animating a bar representing fractions that change with time

**URL:** <https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806>\
**Category:** Visualization\
**Tags:** makie\
**Created:** [October 16, 2022, 4:08pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806 "2022-10-16T16:08:50Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 16, 2022, 4:08pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/1 "2022-10-16T16:08:51Z")

</div>

I want to make a **single stacked bar** where the differerent colors will show the fraction of some quantity. I get errors when I try to animate it:

MWE

```julia
using GLMakie
fig = Figure()
COLORS = [
    "#7143E0",
    "#0A9A84",
    "#171A2F",
    "#F30F0F",
    "#465F00",
    "#701B80",
]

fracax = Axis(fig[1,1]; width = 50, limits = (0,1,0,1))
barpos = Observable(fill(0.5, length(COLORS)))
stacks = Observable(collect(1:length(COLORS)))
heights = Observable(fill(0.1, length(COLORS)))
colors = Observable(to_color.(COLORS))
barplot!(fracax, barpos, heights; width = 1, gap = 0, stack=stacks, color = colors)

display(fig)

# New fractions coming in
heights.val = [0.1, 0.2, 0.5]
barpos.val = [0.5 for k in 1:3]
stacks.val = collect(1:3)
colors.val = [to_color(COLORS[k]) for k in 1:3]

# Errors:
notify.((heights, barpos, stacks, colors))

```

error:

```julia
ERROR: Metadata array needs to have same length as data.
                    Found 24 data items, and 6 metadata items

```

So, how can I animate this bar plot:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/9/0967ca63a232973f86927bebe16f43da3d0aca1b.png)

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 16, 2022, 4:53pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/2 "2022-10-16T16:53:15Z")

</div>

Except for line #3

```julia
colors = [ ...

```

which I had to change to

```julia
COLORS = [ ...

```

your example works for me.

```julia
julia> versioninfo()
Julia Version 1.8.2
Commit 36034abf26 (2022-09-29 15:21 UTC)
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 24 × AMD Ryzen 9 3900X 12-Core Processor
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-13.0.1 (ORCJIT, znver2)
  Threads: 4 on 24 virtual cores

(@v1.8) pkg> st
Status `C:\Users\Oli\.julia\environments\v1.8\Project.toml`
  [e9467ef8] GLMakie v0.7.0

```

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/7/d7c649eec2a85c1777139c1df21cc97edf0f860a.png)

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 16, 2022, 4:59pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/3 "2022-10-16T16:59:41Z")

</div>

I’ve updated the COLORS typo, however when I Run the code as is I get the error I posted:

```julia
ERROR: Metadata array needs to have same length as data.
                    Found 24 data items, and 6 metadata items
Stacktrace:
   [1] error(s::String)
     @ Base .\error.jl:35
   [2] #meta#122
     @ C:\Users\datse\.julia\packages\GeometryBasics\6JxlJ\src\metadata.jl:125 [inlined]     
   [3] pointmeta(mesh::GeometryBasics.Mesh{2, Float32, GeometryBasics.Ngon{2, Float32, 3, Point{2, Float32}}, GeometryBasics.SimpleFaceView{2, Float32, 3, GeometryBasics.OffsetInteger{-1, UInt32}, Point{2, Float32}, GeometryBasics.NgonFace{3, GeometryBasics.OffsetInteger{-1, UInt32}}}}; meta_data::Base.Pairs{Symbol, Vector{ColorTypes.RGBA{Float32}}, Tuple{Symbol}, NamedTuple{(:color,), Tuple{Vector{ColorTypes.RGBA{Float32}}}}})
     @ GeometryBasics C:\Users\datse\.julia\packages\GeometryBasics\6JxlJ\src\meshes.jl:253  
   [4] (::GLMakie.var"#238#241")(mesh::GeometryBasics.Mesh{2, Float32, GeometryBasics.Ngon{2, Float32, 3, Point{2, Float32}}, GeometryBasics.SimpleFaceView{2, Float32, 3, GeometryBasics.OffsetInteger{-1, UInt32}, Point{2, Float32}, GeometryBasics.NgonFace{3, GeometryBasics.OffsetInteger{-1, UInt32}}}}, color::Vector{ColorTypes.RGBA{Float32}})
     @ GLMakie C:\Users\datse\.julia\packages\GLMakie\K6iJk\src\drawing_primitives.jl:466    
   [5] #invokelatest#2
     @ .\essentials.jl:729 [inlined]
   [6] invokelatest
     @ .\essentials.jl:726 [inlined]
   [7] #15

```

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 16, 2022, 5:00pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/4 "2022-10-16T17:00:08Z")

</div>

Okay, you have a newer version of GLMakie. Updating now…

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 17, 2022, 9:20am UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/5 "2022-10-17T09:20:24Z")

</div>

Alright, I’ve updated Makie, and the original code works. However, it doesn’t work when I try to animate them. E.g.,

```julia
using GLMakie
fig = Figure()
COLORS = [
    "#7143E0",
    "#0A9A84",
    "#171A2F",
    "#F30F0F",
    "#465F00",
    "#701B80",
]
fracax = Axis(fig[1,1]; width = 50, limits = (0,1,0,1))
barpos = Observable(fill(0.5, length(COLORS)))
stacks = Observable(collect(1:length(COLORS)))
heights = Observable(fill(0.1, length(COLORS)))
colors = Observable(to_color.(COLORS))
barplot!(fracax, barpos, heights; width = 1, gap = 0, stack=stacks, color = colors)
display(fig)

# New fractions coming in
heights.val = [0.1, 0.2]
barpos.val = [0.5 for k in 1:2]
stacks.val = collect(1:2)
colors.val = [to_color(COLORS[k]) for k in 1:2]
# Works:
notify.((heights, barpos, stacks, colors))

# New fractions coming in
heights.val = [0.1, 0.2, 0.5]
barpos.val = [0.5 for k in 1:3]
stacks.val = collect(1:3)
colors.val = [to_color(COLORS[k]) for k in 1:3]
# Errors:
notify.((heights, barpos, stacks, colors))

```

the last line will error with

```julia
ERROR: BoundsError: attempt to access 2-element Vector{Int64} at index [[1, 2, 3]]
Stacktrace:
  [1] throw_boundserror(A::Vector{Int64}, I::Tuple{Vector{Int64}})
    @ Base .\abstractarray.jl:703
  [2] checkbounds
    @ .\abstractarray.jl:668 [inlined]
  [3] _getindex
    @ .\multidimensional.jl:874 [inlined]
  [4] getindex
    @ .\abstractarray.jl:1236 [inlined]
  [5] stack_grouped_from_to(i_stack::Vector{Int64}, y::Vector{Float32}, grp::NamedTuple{(:x,), Tuple{Vector{Float64}}})
    @ Makie C:\Users\datse\.julia\packages\Makie\D0WIp\src\basic_recipes\barplot.jl:119      
  [6] (::Makie.var"#calculate_bars#433"{Observable{Vector{ColorTypes.RGBA{Float32}}}, Observable{Vector{Vec{2, Float32}}}, Observable{Vector{Vec{2, Float32}}}, Observable{Vector{Tuple{String, Point{2, Float32}}}}})(xy::Vector{Point{2, Float32}}, fillto::MakieCore.Automatic, offset::Float64, width::Int64, dodge::MakieCore.Automatic, n_dodge::MakieCore.Automatic, gap::Int64, dodge_gap::Float64, stack::Vector{Int64}, dir::Symbol, bar_labels::Nothing, flip_labels_at::Float64, label_color::Symbol, color_over_background::MakieCore.Automatic, color_over_bar::MakieCore.Automatic, label_formatter::typeof(Makie.bar_label_formatter), label_offset::Int64) @ Makie C:\Users\datse\.julia\packages\Makie\D0WIp\src\basic_recipes\barplot.jl:230      

```

So there is some indexing problem, or I am not using `notify` correctly.

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 17, 2022, 9:27am UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/6 "2022-10-17T09:27:26Z")

</div>

I have solved my problem by realizing that I can only make the height an observable and setting the height of fractions that don’t exist to 0. So now I plot all fractions from the start, and set those that have 0 fraction to 0.

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 17, 2022, 11:03am UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/7 "2022-10-17T11:03:03Z")

</div>

Desynchronized observable arrays problem strikes again…

---

<div class="post-metadata">

**Author:** ![Datseris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/datseris/32/13406_2.png) [@Datseris](https://discourse.julialang.org/u/Datseris)\
**Post date:** [October 17, 2022, 11:14am UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/8 "2022-10-17T11:14:02Z")

</div>

Is there a known solution to this? I thought that `notify.()` with broadcasting wouldn’t work, because in the end of the day the broadcasting is sequantial…

---

<div class="post-metadata">

**Author:** ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)\
**Post date:** [October 17, 2022, 5:15pm UTC](https://discourse.julialang.org/t/animating-a-bar-representing-fractions-that-change-with-time/88806/9 "2022-10-17T17:15:26Z")

</div>

We have different ideas but haven’t had the time to try them for real yet.
