# Race condition in online plotting with Makie

I’m time stepping a problem and want to plot various quantities as the solver progresses. Inspired by this post, I came up with the following:

``````using Makie
using AbstractPlotting.MakieLayout
using AbstractPlotting
using ProgressMeter
``````

Some fake data, in every time step, I would set the values of `y[i]` and `y2[i]`:

``````x = range(0, stop=1, length=1000)
y = sin.(2π*x)
y2 = cos.(2π*x)
``````

Then, I set up the scene+layout, create some `Node`s and plot them:

``````scene,layout = layoutscene(resolution=(800,600))

axs = layout[1:2,1] = [LAxis(scene) for i=1:2]
ii = Node(1) # Current time step
xplot = lift(i -> view(x, 1:i), ii)
yplot = lift(i -> view(y, 1:i), ii)
yplot2 = lift(i -> view(y2, 1:i), ii)

# # A single line works
# lines!(axs[1], xplot)

# This leads to some kind of race condition
lines!(axs[1], xplot, yplot)
lines!(axs[2], xplot, yplot2)

display(scene) # Show Makie window

plot_interval = 15
@showprogress for i in eachindex(x)
if i%plot_interval == 0
ii[] = i

# Is this the best way to update limits?
autolimits!.(axs)
Makie.update!(scene)
end
end
``````

This leads to the following error:

``````ERROR: LoadError: DimensionMismatch("arrays could not be broadcast to a common size; got a dimension with lengths 30 and 15")
Stacktrace:
[7] convert_arguments(::AbstractPlotting.PointBased, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}) at /Users/jagot/.julia/packages/AbstractPlotting/lGPof/src/conversions.jl:190
[8] convert_arguments(::Type{Lines{...}}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::Vararg{Any,N} where N; kw::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at /Users/jagot/.julia/packages/AbstractPlotting/lGPof/src/conversions.jl:43
[9] convert_arguments(::Type{Lines{...}}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}, ::SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}) at /Users/jagot/.julia/packages/AbstractPlotting/lGPof/src/conversions.jl:41
[10] (::AbstractPlotting.var"#201#203"{DataType,Observable{Tuple{Array{Point{2,Float32},1}}}})(::Tuple{}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}) at /Users/jagot/.julia/packages/AbstractPlotting/lGPof/src/interfaces.jl:617
[11] (::Observables.OnUpdate{AbstractPlotting.var"#201#203"{DataType,Observable{Tuple{Array{Point{2,Float32},1}}}},Tuple{Observable{Tuple{}},Observable{Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}}}})(::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:218
[12] setindex!(::Observable{Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}}, ::Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}; notify::Observables.var"#6#8") at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:130
[13] setindex! at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:126 [inlined]
[14] MapUpdater at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:241 [inlined]
[15] (::Observables.OnUpdate{Observables.MapUpdater{typeof(tuple),Tuple{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}},SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}},Tuple{Observable{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}},Observable{SubArray{Float64,1,Array{Float64,1},Tuple{UnitRange{Int64}},true}}}})(::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:218
[16] setindex!(::Observable{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}; notify::Observables.var"#6#8") at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:130
[17] setindex!(::Observable{StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}}, ::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:126
[18] (::Observables.MapUpdater{var"#51#52",StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}})(::Int64) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:241
[19] (::Observables.OnUpdate{Observables.MapUpdater{var"#51#52",StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}},Tuple{Observable{Int64}}})(::Int64) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:218
[20] setindex!(::Observable{Int64}, ::Int64; notify::Observables.var"#6#8") at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:130
[21] setindex!(::Observable{Int64}, ::Int64) at /Users/jagot/.julia/packages/Observables/0wrF6/src/Observables.jl:126
``````

which I interpret as somehow, it tries to update the plot, before both `xplot` and `yplot` have been updated.

How can I solve this?

Because of the synchronous update of the Observables, this usually happens. The way around it is to pass an observable vector of points, in your case:

``````points1 = lift(i->Point2f0.(view(x, 1:i), view(y, 1:i)), ii)
points2 = lift(i->Point2f0.(view(x, 1:i), view(y2, 1:i)), ii)
lines!(axs[1], points1)
lines!(axs[2], points2)
``````

This line is unnecessary:

``````Makie.update!(scene)
``````

This works very nicely, thank you!