-
Notifications
You must be signed in to change notification settings - Fork 50
Rectangle/bbox layouts in a Figure #740
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
One possible way to do automatic rectangle packing: https://github.com/laserson/squarify @almarklein have you done something like this before? Allow bboxes for subplot viewport rects to be defined, and then when a viewport rect is resized all the other rects should adjust accordinlgy. |
One observation is that sometimes you want to position something in absolute pixels, and sometimes as a fraction of the parent's space. In visvis I therefore positioned widget-objects like this (taken from the visvis docs):
But this is a bit weird/confusing. Plus very often you want a relative position with some offset. So in visvis2 (wip) I borrowed an approach from CSS, each item in the rect is a string e.g. "120px", "50%" or "50% - 20px". See https://github.com/pygfx/visvis2/blob/3e3e9d785c34d3170433c78595390f2304185df3/visvis2/_view.py#L33-L39 I've implemented something similar in pygfx/pygfx#954 (not sure if that will stay). |
If you want more elaborate layout you should probably implement container objects that position their children in a specific way, similar to CSS flexbox and the like. But that'd be a lot more work (it's harder than it looks). |
Ah I actually just did this! https://github.com/fastplotlib/fastplotlib/pull/740/files#diff-44de8531560bd88b7488ae543fbd3ff464555037e40be4d4d26b5fec8a17ace5R91-R96 I was wondering if you knew anything about auto-packing/docking algorithms. It's easy to find GUI toolkits that have it but I can't find any explanation of the backend algorithms anywhere. |
Ah. I did stuff like that in Flexx, but there I could leverage HTML/CSS. I remember that in the early days Jupyterlab used some custom layout engine, but I cannot find it anymore. I suspect they moved to using CSS Flexbox. I would recommend looking at what Matplotlib does, e.g. here: https://github.com/matplotlib/matplotlib/blob/6fc8169112a42e3f6f55793a6b56159cd8ff69d7/lib/matplotlib/figure.py#L2677 A note of warning: widget layout can be a pretty deep rabbit-hole 😉 |
Thanks! I think we'll just have a free-form drag & resize subplots on the canvas and block overlaps, and have another mode that uses a simple tiling algorithm maybe from squarify. This answer on stackoverflow is very good: https://stackoverflow.com/a/306332 and this demo 😄 https://silentmatt.com/rectangle-intersection/ |
Ok I've got the basics down! 🥳 Next step, integrate this mess into flex_layout-2025-03-01_04.45.06.mp4@almarklein Additional pointer control might be useful to implement in I found how it can be done in the browser: https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API#locked_state |
Idea: Instead of putting all the layout management logic inside the Figure class we keep it as separate classes. Merge the implementation of the subplot Frame stuff into the Basically to summarize: We make:
The For To the current |
I think layout manager sounds like a nice way to abstract, and then users can specify the layout they want via string when they instantiate a plot fig = fpl.Figure(layout="grid") I think by default, we would want to maintain the grid layout we have now. |
Also, would squarify be for making rectangular subplots of different sizes and tiling them all together? If that's the case, could we not also use squarify for making our grids too? Fixed rectangles that get tiles together in a particular shape. Or maybe I am not understanding what the the squarify layout would be for |
Yes squarify is for tiling rects of diff sizes. I think it's overkill for a simple grid plot layout though so we should keep them separate. |
In the flex and squarify layouts we can also have a swap method to swap subplot rects |
I think we have an issue to be able to hide the cursor, which is also convenient for games. But that means you have to draw some sort of cursor yourself. Is that what you mean? AFAIK You cannot keep the OS's cursor and stop it from moving. |
This is what I meant, I'll do another search and see if there is such a thing. Otherwise once we have our own cursors. I just realized a grid layout can just be managed by a flex layout with fractional extents, this will make the implementations easier. |
so what's left is:
rects-2025-03-08_02.43.12.mp4@almarklein related to pygfx/pygfx#492, would it be possible to have an underlay render pass which also doesn't have a depth butter? For rendering the box frame of the subplot, subplot title and resize handles? |
a446428
to
c11acab
Compare
We can allow one inset plot area within a subplot, arbitrary overlaps would be a mess with the screenspace camera and if a user wants many overlapping plots they should probably make them separate anyways |
Let's do insets and add/remove subplots and row/columms in another PR. |
@almarklein would be great to get your thoughts on this PR! 😄 |
# Conflicts: # fastplotlib/layouts/_engine.py
Co-authored-by: Almar Klein <almar@almarklein.org>
c7b4daf
to
f6263a3
Compare
📚 Docs preview built and uploaded! https://www.fastplotlib.org/ver/figure-rect-mode |
@clewis7 should be gtg! 🥳 |
All tests using pygfx@main passing, docs built! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥳 🥳 🥳
Flexible rectangle/bbox layouts with resizable and draggable subplots!
Summary of this PR:
layouts._engine
, which is a module for layout engines.WindowLayout
is a layout with subplots that can be moved and resized. A subplot is defined with a rect or extent.GridLayout
is a subclass ofWindowLayout
using fixed extents.Frame
class. This contains theplane
Mesh,resize_handle
Point object, and the subplot titleTextGraphic
. It also manages theSubplot
viewport rect and the dock viewport rects.RectManager
which manages theFrame
rect, makes it easy to manage rect, fractional rects, extent, etc. in one class. This allowsFrame
to use arect
orextent
in absolute screen space or as fraction of the canvas.Users can specify rects or extents, in absolute pixels or as fractions of the canvas.
Future PRs will allow adding/removing a subplot and insets.
closes #315 closes #616