You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to suggest a change to the API, which is somewhat of an extension of the "API wishlist" in #725.
I'm assuming the API will be modified so that basic plotting command (plot, lines, heatmap etc.) return a plot object which can then be added into a scene or axis, as in the example in #725.
Suggested change
The basic use pattern should be changed from observable parameters to plot commands (push!(ax, plot(Node(data)))), to observable plot objects over plain data (push!(ax, Node(plot(data)))).
Support for the former pattern can be dropped to make for a more consistent interface (and guard against the problem described below). Alternatively, it can be implemented easily on top of this API, with definitions such as
# (1)
i = Observable(5)
x = @lift rand($i)
y = @lift rand($i)
c = @lift rand($i)
push!(ax, lines(x, y, color=c))
# or the current:
# lines!(ax, x, y, color=c)
would become
# (2)
i = Observable(5)
lns = lift(i) do i
x = rand(i)
y = rand(i)
c = rand(i)
lines(x, y, color=c)
end
push!(ax, lns)
Example (1) doesn't actually work because of the synchronous update problem: updating i updates x first, which updates the lines plot and throws an error, since x and y are of different length. Example (2) would achieve an atomic update of the plot, so there is no such issue.
A smaller advantage is that listening on the plot can make sense sometimes. Arguably on(lns) do lns; update_limits!(lns) end is better than on(i) do _; update_limits!(lns) end as it expresses the intent more precisely, and therefore more robust to changes in how lns is constructed.
Current workarounds
A possible workaround in the current design is doing lines(Point2.(x,y)), but this trick doesn't work for the color kwarg. It also wouldn't work for heatmap(x,y,z).
I was able to get synchronous updates for my own code by defining ad-hoc intermediate object and recipes for each such plot. (You can do heatmap(::Observable{MyCustomHeatmapDataStruct}) with a type recipe. Dealing with kwargs requires a full recipe as far as I can see). Changing the API would solve the problem more generally for all plot types, and for both their positional and keyword arguments.
This discussion was converted from issue #798 on August 22, 2024 12:44.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
I would like to suggest a change to the API, which is somewhat of an extension of the "API wishlist" in #725.
I'm assuming the API will be modified so that basic plotting command (
plot
,lines
,heatmap
etc.) return a plot object which can then be added into a scene or axis, as in the example in #725.Suggested change
The basic use pattern should be changed from observable parameters to plot commands (
push!(ax, plot(Node(data)))
), to observable plot objects over plain data (push!(ax, Node(plot(data)))
).Support for the former pattern can be dropped to make for a more consistent interface (and guard against the problem described below). Alternatively, it can be implemented easily on top of this API, with definitions such as
The problem
The main advantage is solving problems with update synchronization, as described in this docs section http://makie.juliaplots.org/dev/interaction.html#Problems-With-Synchronous-Updates.
For example this:
would become
Example (1) doesn't actually work because of the synchronous update problem: updating
i
updates x first, which updates the lines plot and throws an error, sincex
andy
are of different length. Example (2) would achieve an atomic update of the plot, so there is no such issue.A smaller advantage is that listening on the plot can make sense sometimes. Arguably
on(lns) do lns; update_limits!(lns) end
is better thanon(i) do _; update_limits!(lns) end
as it expresses the intent more precisely, and therefore more robust to changes in howlns
is constructed.Current workarounds
A possible workaround in the current design is doing
lines(Point2.(x,y))
, but this trick doesn't work for thecolor
kwarg. It also wouldn't work forheatmap(x,y,z)
.I was able to get synchronous updates for my own code by defining ad-hoc intermediate object and recipes for each such plot. (You can do
heatmap(::Observable{MyCustomHeatmapDataStruct})
with a type recipe. Dealing with kwargs requires a full recipe as far as I can see). Changing the API would solve the problem more generally for all plot types, and for both their positional and keyword arguments.Beta Was this translation helpful? Give feedback.
All reactions