# How can I trigger Node(array) after changing array element in Makie?

**URL:** https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414
**Category:** Visualization
**Tags:** makie
**Created:** [May 19, 2021, 5:23am UTC](https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414 "2021-05-19T05:23:47Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![LSellers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lsellers/32/25221_2.png) [@LSellers](https://discourse.julialang.org/u/LSellers)
#### Post date: [May 19, 2021, 5:23am UTC](https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414/1 "2021-05-19T05:23:47Z")

</div>

The root issue is that when I have `data = Node([1 2 3 4 5 6])`, I cannot force `data` to update elsewhere by simply changing the value of one element (`data[][1] = 0`). As far as I can tell, I have to assign `data[] = [0 2 3 4 5 6]`, or `data[] = data[]` after changing just the element etc, which wastes resources and becomes prohibitive for big arrays.

Is there something w/ the equivalent of bash shell’s `touch filename` that will trigger the equivalent of `data[] = data[]` without doing the assignment?

```julia
using Makie
myn=Node(fill(0, 5))
println(to_value(myn)) #--------> [0,0,0,0,0]
on(println, myn)
myn[] = fill(1, 5) # prints [1,1,1,1,1]
myn[][2:3] = [2,3] # nothing prints 
println(to_value(myn)) #----------> [1,2,3,1,1]

```

And yes I can create an array of nodes `anodes = Node.(fill(0,5)` and then use `onany(println, anodes...)` to trigger, but this becomes slow very quickly with size.

In particular, I want an animated image to live update `display(f)` as the data changes in the spirit of the following code…

```julia
using Makie
data = fill(0, (100,100)
f = Figure(resolution = (100,100))
Makie.Axis(f[1, 1], aspect = DataAspect(), xticks = [], yticks=[])
display(f)
image!(data)

for i in [1:10, 11:20, 51:60]
    data[i] = fill(1,10)
    sleep(.001)
end

```

I’ve tried many things that don’t quite work… One thing that kind of “worked” was just throwing `image!(data)` inside the loop; but this creates memory problems b/c the memory from previous images is not released.

How can I do this without reassigning the entire `data` array?

many many thanks - Makie looks like it can do great things, but i don’t know how to/if i can get it to do the simple things I want 😕

@sdanisch ?

---

<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: [May 19, 2021, 7:31am UTC](https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414/2 "2021-05-19T07:31:05Z")

</div>

`data[] = data[]` doesn’t actually copy anything, it is equivalent to doing `notify(data)`, so it just triggers listeners. Of coure you are right that resources are wasted by doing the computations that are triggered for the whole array and not just the changed values, but we currently don’t have the pipeline in place to distinguish between such cases. For example, if some following step scaled the image by the `mean`, that would still have to be run on the whole array, even if just one number changes.

But for image sizes of `(100, 100)` it should be quite fast to update these images, I’ve used fluent updates of images that were much larger than that. Maybe your sleep interval is too low as well?

If you do `image!` over and over again, you just layer these on top of each other, so of course the memory is not released. But that has to be strictly slower than just changing the whole array inside the node anyway, because it does that step plus all the setup steps for new plot objects.

---

<div class="post-metadata">

### Author: ![LSellers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lsellers/32/25221_2.png) [@LSellers](https://discourse.julialang.org/u/LSellers)
#### Post date: [May 20, 2021, 1:16am UTC](https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414/3 "2021-05-20T01:16:44Z")

</div>

thanks jules.  
A single `data[]=data[]` (or `notify`) call takes 200ms w/ a 2k by 2k array on my machine. so not ideal for smooth real-time processing. is my machine just slow?

I see the point about having things in sync, but i’d also gladly use that option with the caveat 🙂 … changing subarrays/elements with or without notification as needed. e.g. using something like ’ `view_obs()` ’ vs `view()`

for the former case I’m looking into using `Sampler` type based on advice from a different post, but haven’t succeeded in propagation yet (maybe it’s impossible). I’ll post here if I can get it to work.  
thanks again.

---

<div class="post-metadata">

### Author: ![LSellers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lsellers/32/25221_2.png) [@LSellers](https://discourse.julialang.org/u/LSellers)
#### Post date: [May 21, 2021, 5:07pm UTC](https://discourse.julialang.org/t/how-can-i-trigger-node-array-after-changing-array-element-in-makie/61414/4 "2021-05-21T17:07:19Z")

</div>

So `Sampler` type works well and is available when using GLMakie. for me functionally accessing the `Sampler` object works like calling `view` that propagates the updated portion to the image.

Regarding the `data[]=data[]` call, using it provided a speedup proportional to the size of the Sampler array to the data array. So in my case that was a speed up of at least 100x

[https://github.com/JuliaPlots/GLMakie.jl/blob/master/test/glmakie\_tests.jl#L34](https://github.com/JuliaPlots/GLMakie.jl/blob/master/test/glmakie_tests.jl#L34)

[https://github.com/SimonDanisch/ShaderAbstractions.jl/blob/master/src/types.jl#L67](https://github.com/SimonDanisch/ShaderAbstractions.jl/blob/master/src/types.jl#L67)

it works perfectly with Matrix{RGBAf0} in Makie. I was originally trying to use it with Float32 array. @sdanisch was awesome enough to show how Float32 could work with a conversion overload. this example uses `heatmap`

```julia
using GLMakie 
using GLMakie.ShaderAbstractions: Sampler

# Missing overload to have Sampler work
AbstractPlotting.el32convert(x::AbstractArray{Float32}) = x

imag = rand(Float32, (2000,2000))
data = Sampler(imag, minfilter=:nearest) # or linear for interpolation
n = 25
f = Figure(resolution = size(imag));
ax = Makie.Axis(f[1, 1], aspect = DataAspect()); 
hidedecorations!(ax)
tightlimits!(ax)
heatmap!(ax, data)
display(f)

@time for i in 1:n
    data[1:400, 1:400] = fill(0f0, 400, 400)
    yield()
end

```
