Skip to content

Commit cf5b11b

Browse files
authored
move viewport rect logic from subplot and docks to Figure (#724)
* move viewport rect logic from subplot and docks to Figure * progress * refactored rect code works well * add tests for viewport rects * figure refactor works, tested backend and passes * cleanup iw * update tests * update right click menu * update imgui figure * add gridplot viewport rect verification screenshots * black complains * remove cell * update docs * include OS in screenshot diff artifacts filename * comments * modify nb test, should work again now * try to make first render look right on github actions * update last groundtruth screenshot
1 parent a141f51 commit cf5b11b

File tree

21 files changed

+478
-397
lines changed

21 files changed

+478
-397
lines changed

.github/workflows/ci-pygfx-release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
- uses: actions/upload-artifact@v4
8383
if: ${{ failure() }}
8484
with:
85-
name: screenshot-diffs-${{ matrix.pyversion }}-${{ matrix.imgui_dep }}-${{ matrix.notebook_dep }}
85+
name: screenshot-diffs-${{ matrix.os }}-${{ matrix.pyversion }}-${{ matrix.imgui_dep }}-${{ matrix.notebook_dep }}
8686
path: |
8787
examples/diffs
8888
examples/notebooks/diffs

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ jobs:
8888
- uses: actions/upload-artifact@v4
8989
if: ${{ failure() }}
9090
with:
91-
name: screenshot-diffs-${{ matrix.pyversion }}-${{ matrix.imgui_dep }}-${{ matrix.notebook_dep }}
91+
name: screenshot-diffs-${{ matrix.os }}-${{ matrix.pyversion }}-${{ matrix.imgui_dep }}-${{ matrix.notebook_dep }}
9292
path: |
9393
examples/diffs
9494
examples/notebooks/diffs

docs/source/api/layouts/figure.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@ Properties
2323
Figure.cameras
2424
Figure.canvas
2525
Figure.controllers
26+
Figure.mode
2627
Figure.names
2728
Figure.renderer
2829
Figure.shape
30+
Figure.spacing
2931

3032
Methods
3133
~~~~~~~
@@ -36,10 +38,9 @@ Methods
3638
Figure.clear
3739
Figure.close
3840
Figure.export
41+
Figure.export_numpy
3942
Figure.get_pygfx_render_area
4043
Figure.open_popup
4144
Figure.remove_animation
42-
Figure.render
4345
Figure.show
44-
Figure.start_render
4546

docs/source/api/layouts/imgui_figure.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,11 @@ Properties
2525
ImguiFigure.controllers
2626
ImguiFigure.guis
2727
ImguiFigure.imgui_renderer
28+
ImguiFigure.mode
2829
ImguiFigure.names
2930
ImguiFigure.renderer
3031
ImguiFigure.shape
32+
ImguiFigure.spacing
3133

3234
Methods
3335
~~~~~~~
@@ -39,11 +41,10 @@ Methods
3941
ImguiFigure.clear
4042
ImguiFigure.close
4143
ImguiFigure.export
44+
ImguiFigure.export_numpy
4245
ImguiFigure.get_pygfx_render_area
4346
ImguiFigure.open_popup
4447
ImguiFigure.register_popup
4548
ImguiFigure.remove_animation
46-
ImguiFigure.render
4749
ImguiFigure.show
48-
ImguiFigure.start_render
4950

docs/source/api/layouts/subplot.rst

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ Properties
3131
Subplot.name
3232
Subplot.objects
3333
Subplot.parent
34-
Subplot.position
3534
Subplot.renderer
3635
Subplot.scene
3736
Subplot.selectors
@@ -58,12 +57,9 @@ Methods
5857
Subplot.clear
5958
Subplot.delete_graphic
6059
Subplot.get_figure
61-
Subplot.get_rect
6260
Subplot.insert_graphic
6361
Subplot.map_screen_to_world
6462
Subplot.remove_animation
6563
Subplot.remove_graphic
66-
Subplot.render
6764
Subplot.set_title
68-
Subplot.set_viewport_rect
6965

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
GridPlot test viewport rects
3+
============================
4+
5+
Test figure to test that viewport rects are positioned correctly
6+
"""
7+
8+
# test_example = true
9+
# sphinx_gallery_pygfx_docs = 'hidden'
10+
11+
import fastplotlib as fpl
12+
import numpy as np
13+
14+
15+
figure = fpl.Figure(
16+
shape=(2, 3),
17+
size=(700, 560),
18+
names=list(map(str, range(6)))
19+
)
20+
21+
np.random.seed(0)
22+
a = np.random.rand(6, 10, 10)
23+
24+
for data, subplot in zip(a, figure):
25+
subplot.add_image(data)
26+
subplot.docks["left"].size = 20
27+
subplot.docks["right"].size = 30
28+
subplot.docks["bottom"].size = 40
29+
30+
figure.show()
31+
32+
33+
# NOTE: `if __name__ == "__main__"` is NOT how to use fastplotlib interactively
34+
# please see our docs for using fastplotlib interactively in ipython and jupyter
35+
if __name__ == "__main__":
36+
print(__doc__)
37+
fpl.loop.run()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"""
2+
ImageWidget test viewport rects
3+
===============================
4+
5+
Test Figure to test that viewport rects are positioned correctly in an image widget
6+
"""
7+
8+
# test_example = true
9+
# sphinx_gallery_pygfx_docs = 'hidden'
10+
11+
import fastplotlib as fpl
12+
import numpy as np
13+
14+
np.random.seed(0)
15+
a = np.random.rand(6, 15, 10, 10)
16+
17+
iw = fpl.ImageWidget(
18+
data=[img for img in a],
19+
names=list(map(str, range(6))),
20+
figure_kwargs={"size": (700, 560)},
21+
)
22+
23+
for subplot in iw.figure:
24+
subplot.docks["left"].size = 10
25+
subplot.docks["bottom"].size = 40
26+
27+
iw.show()
28+
29+
figure = iw.figure
30+
31+
# NOTE: `if __name__ == "__main__"` is NOT how to use fastplotlib interactively
32+
# please see our docs for using fastplotlib interactively in ipython and jupyter
33+
if __name__ == "__main__":
34+
print(__doc__)
35+
fpl.loop.run()

examples/notebooks/nb_test_utils.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,26 @@ def plot_test(name, fig: fpl.Figure):
9494
if not TESTING:
9595
return
9696

97+
# otherwise the first render is wrong
98+
if fpl.IMGUI:
99+
# there doesn't seem to be a resize event for the manual offscreen canvas
100+
fig.imgui_renderer._backend.io.display_size = fig.canvas.get_logical_size()
101+
# run this once so any edge widgets set their sizes and therefore the subplots get the correct rect
102+
# hacky but it works for now
103+
fig.imgui_renderer.render()
104+
105+
fig._set_viewport_rects()
106+
# render each subplot
107+
for subplot in fig:
108+
subplot.viewport.render(subplot.scene, subplot.camera)
109+
110+
# flush pygfx renderer
111+
fig.renderer.flush()
112+
113+
if fpl.IMGUI:
114+
# render imgui
115+
fig.imgui_renderer.render()
116+
97117
snapshot = fig.canvas.snapshot()
98118
rgb_img = rgba_to_rgb(snapshot.data)
99119

examples/notebooks/quickstart.ipynb

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,22 +1695,6 @@
16951695
"figure_grid[\"top-right-plot\"]"
16961696
]
16971697
},
1698-
{
1699-
"cell_type": "code",
1700-
"execution_count": null,
1701-
"id": "cb7566a5",
1702-
"metadata": {
1703-
"collapsed": false,
1704-
"jupyter": {
1705-
"outputs_hidden": false
1706-
}
1707-
},
1708-
"outputs": [],
1709-
"source": [
1710-
"# view its position\n",
1711-
"figure_grid[\"top-right-plot\"].position"
1712-
]
1713-
},
17141698
{
17151699
"cell_type": "code",
17161700
"execution_count": null,
Lines changed: 3 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)