New API for Plot Objects #4189
Replies: 11 comments
-
So each scene has
in terms of updateable fields that a plot object might care about. Which ones of these should be mirrored on the plot object side so that the internal logic can be set up without a scene being present? |
Beta Was this translation helpful? Give feedback.
-
I should add to the wishlist:
If we disconnect the |
Beta Was this translation helpful? Give feedback.
-
Oh and another thing, in my |
Beta Was this translation helpful? Give feedback.
-
And now that Simon mentioned events - being able to lock/consume events would be nice. For example, if you have a slider next to a 3D plot and drag to far, you rotate the 3D plot. Or if you select a |
Beta Was this translation helpful? Give feedback.
-
The slider thing is just bad dragging logic in the scene, my mousestatemachine code in MakieLayout guards against dragging in from the outside. The LMenu thing with the slider is because right now, the slider accepts clicks in its whole subscene area, because the line is so thin that it's annoying to have to click it pixel perfect.. But then even if an LMenu covers part of the slider scene, the slider scene event doesn't know that and still triggers. It's not such an easy problem I think :) |
Beta Was this translation helpful? Give feedback.
-
I'm following a game engine tutorial series on the side. The event implementation they have essentially goes as such:
Every so often I wonder if that design would be better for Makie. You can more or less translate From the user perspective adding some behavior based on an event would then require implementing function AbstractPlotting.handle!(plot, event::SpecificEventType)
# do something
return true # true = event consumed, false = event continues to be passed
end |
Beta Was this translation helpful? Give feedback.
-
I don't know the internals at all well (yet), but in reconsidering the API, I'll throw up a deliberately-exaggerated proposed mental model: that plot objects should be only minor elaborations of In a bit more detail, what I mean is that Parallel to plot objects would be "views", which include a layout hierarchy, camera settings, and transforms, and "actions" (events and their handers). Plot objects could literally be stored as a flat (and completely unorganized) list in the figure in which they appear, though I suspect each should be assigned a I think that's pretty consistent with what's in the API demo in #725 (comment). The key thing seems to be to think of One apparent loss would be in interactivity: naively, Again, I'm a total newbie here, speaking without the long experience of Makie's designers. |
Beta Was this translation helpful? Give feedback.
-
That sounds like a good plan, and I've been contemplating a lot to turn the plot object into something that is purely a spec of what should be plotted... It's just not 100% trivial to get there, under the constraints of usability, type inference, compile times and interactivity( with the event system). |
Beta Was this translation helpful? Give feedback.
-
I think it could be quite hard to have plot objects that just store their input arguments, as the connection of these arguments to some plottable outcome is often the heart of the plot object implementation. So I think it's fine that a scatter object can only really be displayed once it's pushed to a scene. But it's important that it's internal logic is not dependent on its "mother scene" which it was first pushed to. Your idea with Expr like objects seems really well suited to a separate effort for a recipe system for Makie. But I'm not sure if the actual plot objects can be so reduced in scope. |
Beta Was this translation helpful? Give feedback.
-
Again, I don't have your experience. But I don't see any fundamental obstacle. Basically, I'm proposing that one make content orthogonal from layout orthogonal from rendering. That would suggest that you have some objects that represent each of these pillars. That doesn't prevent you from creating hybrid objects that combine one or more of each, plus any "glue" fields needed to make them interoperate. AbstractPlotting and its internal MakieLayout seems fairly close to this already, so I don't mean to sell this as a more fundamental shift than it is. But my naive impression is that currently things are a bit mixed together. For example, the first call to using AbstractPlotting, AbstractTrees
using AbstractPlotting.MakieLayout
AbstractTrees.children(node::Core.Compiler.Timings.Timing) = node.children
AbstractTrees.printnode(io::IO, node::Core.Compiler.Timings.Timing) = print(io, node.time/10^6, ": ", node.mi_info.mi)
scene, layout = layoutscene()
function time_inference()
Core.Compiler.Timings.reset_timings()
Core.Compiler.__set_measure_typeinf(true)
LAxis(scene)
Core.Compiler.__set_measure_typeinf(false)
Core.Compiler.Timings.close_current_timer()
return Core.Compiler.Timings._timings[1]
end
tinf = time_inference()
open("/tmp/LAxis.log", "w") do io # or wherever you like to store your temporary files
print_tree(io, tinf, 50)
end and then open up The way I think about it, it seems like it should be possible to define a heirarchy of axes, etc, independent of the actual geometry or rendering. You call that code only when you actually display an object. I'm not necessarily saying that it will end up saving much inference time (it might merely delay it), but the triggered cascade seems like a symptom of mingling among what I naively expect could be independent layers. I don't mean to pick on MakieLayout, as it exhibits several traits that I think should become the default for Makie. And again, I don't have yours and @SimonDanisch's expertise. I'll shut up now and let people know who what they're talking about discuss this 😄. |
Beta Was this translation helpful? Give feedback.
-
No I think you're completely right to question these design decisions. I can only speak for the MakieLayout part, as I didn't write AbstractPlotting. But it grew very organically, and I tried to use the existing functionality to hack together an axis that could be put in a layout and that wouldn't zoom its axis labels together with the content. From there it just got more and more complex, and because no standalone plot objects were available at the time, the whole LAxis thing is written like a hybrid of plot recipe and GUI container object. I would love to make this more streamlined, don't get me wrong :) At least GridLayoutBase got factored out in the process and is now kind of parallel to everything else. Which is nice, but sometimes people are also confused that when a layout contains an object this doesn't mean that the scene contains / renders it. So the separation of concerns is sometimes hard to enforce. One other thing which complicates things is that the layout code depends on getting measurements of things like axis labels. These can be measured only relative to a containing scene. That's another reason why all labels are instantiated as plot objects in the LAxis constructor, so that I can set up the reactive layout for whenever they change in size. |
Beta Was this translation helpful? Give feedback.
-
Current problems
Combined
andPlotSpec
structure is confusing and probably too complex for what it doeserrorbars
does, because there is no API to disconnect those connections and reconnect them when moving the plot object to a different sceneAPI wishlist
Questions
Combined
andPlotSpec
into one?Beta Was this translation helpful? Give feedback.
All reactions