Skip to content

Autogenerate images of parts of the viewer #621

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

TimMonko
Copy link
Contributor

@TimMonko TimMonko commented Mar 13, 2025

References and Motivation

With 0.6.0 on the way, there have been many changes to the UI from 0.5.6, especially when considering the years of napari development. Much of these changes have been done by me, and in recognition of that, I would like to update the current static images used throughout the docs with dynamically generated ones, so that any future UI changes do not require thorough updates of the docs. This PR was originally conceived slightly before, and then discussed at 2025-03-13/14 docs meeting; the docs meeting concluded that this PR should be made quickly, merged, and then checked for any flakiness (since it requires a merge) or appearance issues in the auto-generation. Then, we can make specific updates to the script (or new scripts) in order to improve visualization for various places in the docs. These are presently designed as proof-of-principle and change things as needed. Conceivably, this can also replace images where we hide building up a napari viewer instance, only to take an nbscreenshot. I believe this script method is considerably faster, but does require a bit less intuitive of a setup compared to the screenshot method. Overall, this takes less than 3 seconds to generate over 20 images. I'm aware that many of these are not currently needed in the docs, but may provide inspiration and design principles, even for the autogeneration, moving forward. We'll clean up what exactly is autogenerated in follow-up PRs. In follow ups, we can also consider adding unique stylings to Qt elements on the fly, such as making a certain button of interest have a yellow border.

Useful current places:

  1. viewer tutorial buttons, popups (e.g. we just added grid popup and the buttons below are already out of date),, anything with console, etc. quite a few static images in here
  2. layers tutorial
  3. quick start. console related images
  4. various buttons and images in how to each layer

And in the future, because we can more quickly generate images, we can conceivably use more focused images throughout the docs.

This will require doing something with doc merges as force-orphan to prevent build up of repo size with changing binaries, though nicely, these images are so far quite small in size (comparatively)

Description

In one single file, our goal is to autogenerate various elements of the UI; these are either initially gotten with viewer.screenshot of the current viewer state, or in follow-ups as specific pixmaps of the widgets (or a defined group of widgets). These pixmaps are defined by dictionaries at the top of the file, making it easier to find and contribute to an image of interest. It also serves as models for 'set up' of different element types (popups, menus, other states)

These include:

  1. single widget elements always visible in the UI
  2. menus, and specific submenus
  3. triggered popup widgets, like grid, roll, ndisplay
  4. groups of widgets. these are my favorite, but will take the most thought to define because it allows us to dynamically 'crop' the viewer to areas of interest. Lovely!

The current implementation prioritizes speed, but may need to add some QTimer / sleep events for CI, not sure.

Autogenerated image examples

Viewer and folder structure

image

Single widgets

image

Menus

image

Popups

image

Combined groups of widgets

image

Original PR Description

This is really a draft of trying to autogenerate images that we can use throughout the docs. I think this would also speed up doc generation in certain areas with reusable doc images, so that nbscreenshot would not need to be as frequent. Everything is getting saved into images/_autogenerated and could be used elsewhere.

  1. Tries to autogenerate grabbing and saving many parts of the viewer using the attributes of the viewer

Needs:

  1. Popups are not working right, sometimes they trigger, often its the dims slider popup. I probably need to just directly call the button, but I'm having a tough time figuring out where the buttons live.
  2. I think the timing of things has me really confused. I think QTimer is necessary to wait for things to popup, but I can't figure out why these popups aren't working
  3. Also sometimes the console popups and saves as a screenshot, other times its just the thin dock area prior to the console popup.

Examples of what should appear in autogenerated if CI does it the same was as locally
image

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Mar 13, 2025
@TimMonko
Copy link
Contributor Author

Adding a few links from the community meeting today:
https://simonwillison.net/2022/Oct/14/automating-screenshots/
https://simonwillison.net/2022/Mar/10/shot-scraper/
napari/napari#7678
and look into qt_bot wait

@melissawm
Copy link
Member

Hi @TimMonko - this is the PR I mentioned on zulip: #308

That one is more focused on videos, so might not be helpful but just in case here it is. Cheers!

@TimMonko TimMonko marked this pull request as ready for review March 14, 2025 16:56
@TimMonko
Copy link
Contributor Author

TimMonko commented Mar 14, 2025

@Czaki
Everything is organized in one file now, and the script is not flaky anymore.
QTimer actually seems to create more problems than fewer problems for popups, compared to menus. Perhaps I was implementing incorrectly --though I was using same logic as menus, it would be delayed asynchronously. Strangely, lowering Qtimer for capturing menus to 50ms resulting in incomplete generation of popups. The async part of this is so confusing.

  1. Creates images of many widgets
  2. Creates images of many menu items
  3. Creates images of popups with prep triggers.

We can add / change more and modify callbacks in various ways, but as @willingc we can start with a merged script and go from there.

I hope it's not flaky on anyone else's machine, or CI.

Copy link
Contributor

@willingc willingc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge this as is. I would like to do a pass over the script and change some of the print statements to logging (it will benefit us when running in CI).

@TimMonko
Copy link
Contributor Author

TimMonko commented Mar 15, 2025

Sounds good, the prints were really just for debugging lol. I take them out as things start to work. Definitely anything with prints from me is a 'draft'. Can still merge though if you like

We should be able to see if CI autogenerates correctly

@willingc
Copy link
Contributor

I would like us to merge and iterate on it.

@melissawm
Copy link
Member

Can we add a comment in the script to indicate which images it is generating?

@TimMonko
Copy link
Contributor Author

@melissawm I added much more commenting to try to clarify what is being saved and I hope the code organization is sufficient to be self explanatory. However, if what you mean is to specifically say which images for the docs this is generating, I'm not sure that's a good idea (will be hard to maintain and keep up to date). Please let me know if I haven't accomplished the goal.

I've also added various interactions with the canvas to change the display of various widgets -- we can always be very specific if we have things in mind to demonstrate. At this point, I'm very happy with this implementation, and want us to merge this to check it works on CI, and then we can look to specifically define images of interest that can be used in the docs.

I also added a preliminary, rough implementation of capturing regions of the viewer as defined by the widgets. In the long run, this will be more maintainable than defining the region with our own coordinates (since inevitably these coordinates could move around). Currently, it just crops to the bounds of the defined widgets, for example:

Viewer buttons + Console:
console_and_buttons

Layer list and layer controls
layer_list_and_controls

@melissawm
Copy link
Member

Ok - Maybe I just need more context on what we're accomplishing. Reading this is seems like we are generating one image for the empty viewer, one for the cells3d sample and another for cells3d with the console. My question is - are we supposed to use this script in the future to include all other images? If not, why are we only using those 3?

I don't want to block this though, feel free to merge and iterate on it later!

@TimMonko
Copy link
Contributor Author

@melissawm updated the PR description to fully encapsulate the goals of this PR and the description of every image that is taken.

jni added a commit that referenced this pull request Apr 10, 2025
In #621 and elsewhere, we are discussing the issue of autogenerating
screenshots in the docs. @Czaki brought up the issue that git is very
bad at handling binary blobs, so autogenerating images each time we
build the docs would rapidly blow up the repo clone size.

I think it's clear that we *do* want to autogenerate images, so the
cleanest solution in my opinion is to always squash when pushing to
our gh-pages site (napari.github.io). That history is not particularly
valuable, and indeed we have squashed it once before when it was getting
far too big to work with. Doing it automatically is actually an
improvement.

This PR achieves that by using the `force_orphan` option in the
peaceiris/actions-gh-pages action to always squash the edit history
before pushing to the gh-pages branch.

## References

Zulip discussion:

https://napari.zulipchat.com/#narrow/channel/298358-working-group-documentation/topic/Meeting.202025-03-13.2F14/near/505543160

`force_orphan` documentation:

https://github.com/peaceiris/actions-gh-pages?tab=readme-ov-file#%EF%B8%8F-force-orphan-force_orphan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants