From 21dcd4a243e5efd4f56359ddb5d33b676f0aa2e9 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Mon, 5 Aug 2024 16:32:44 -0400 Subject: [PATCH 1/8] update contributing guide --- CONTRIBUTING.md | 312 ++++++++---------- .../source/for_developers/developer_notes.rst | 0 2 files changed, 146 insertions(+), 166 deletions(-) create mode 100644 docs/source/for_developers/developer_notes.rst diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0786596b4..c9e19ae48 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,242 +1,222 @@ -# Contribution guide +# Contributing Guide -Contributions are welcome! :smile: +`fastplotlib` is a next-generation plotting library built on top of the `pygfx` rendering engine that leverages modern +GPU hardware and new graphics APIs to build large-scale scientific visualizations. We welcome and encourage contributions +from everyone! :smile: -## Installation +This guide explains how to contribute: if you have questions about the process, please +reach out on [GitHub Discussions](https://github.com/fastplotlib/fastplotlib/discussions). -1. Fork the repo to your own GitHub account, click the "Fork" button at the top: +## General Guidelines -![image](https://github.com/kushalkolar/fastplotlib/assets/9403332/82612021-37b2-48dd-b7e4-01a919535c17) +Developers are encouraged to contribute to various areas of development. This could include the addition of new features (e.g. +graphics or selector tools), bug fixes, or the addition of new examples to the [examples gallery](https://fastplotlib.readthedocs.io/en/latest/_gallery/index.html) . Enhancements to documentation and the overall readability of the +code are also greatly appreciated. -2. Clone the repo and install according to the development instructions. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. +Feel free to work on any section of the code that you believe you can improve. More importantly, remember to thoroughly test all +your classes and functions, and to provide clear, detailed comments within your code. This not only aids others in using the library, +but also facilitates future maintenance and further development. -```bash -git clone https://github.com/YOUR_ACCOUNT/fastplotlib.git -cd fastplotlib - -# install all extras in place -pip install -e ".[notebook,docs,tests]" -``` +For more detailed information about `fastplotlib` modules, including design choices and implementation details, visit the +[`For Develeopers`]() section of the package documentation. -> If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any -> time to download the files stored on LFS +## Contributing to the code -3. Checkout the `main` branch, and then checkout your feature or bug fix branch, and run tests: +### Contribution workflow cycle -If your contributions modify how visualizations look, see the "Tests in detail" section at the very bottom. +In order to contribute, you will need to do the following: -```bash -cd fastplotlib +1) Create your own branch +2) Make sure that tests pass +3) Open a Pull Request -git checkout main +The `fastplotlib` package follows the [Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) workflow. In essence, `main` is the primary branch to which no one is allowed to +push directly. All development happens in separate feature branches that are then merged into `main` once we have determined they are ready. When enough changes have accumulated, a new release is +generated. This process includes adding a new tag to increment the version number and uploading the new release to PyPI. -# checkout your new branch from main -git checkout -b my-new-feature-branch +### Creating a development environment -# make some changes, lint with black -black . +You will need a local installation `fastplotlib` which keeps up-to-date with any changes you make. To do so, you will need to fork and clone `fastplotlib` before checking out a new branch. -# run tests from the repo root dir -pytest -v examples -FASTPLOTLIB_NB_TESTS=1 pytest --nbmake examples/notebooks/ +1. Fork the repo to your own GitHub account, click the "Fork" button at the top: -# add your changed files, do not add any changes from screenshot diff dirs -git add my_changed_files +![image](https://github.com/kushalkolar/fastplotlib/assets/9403332/82612021-37b2-48dd-b7e4-01a919535c17) -# commit changes -git commit -m "my new feature" +2. Clone the repo. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. -# push changes to your fork -git push origin my-new-feature-branch +```bash +git clone https://github.com/YOUR_ACCOUNT/fastplotlib.git +cd fastplotlib ``` -4. Finally make a **draft** PR against the `main` branch. When you think the PR is ready, mark it for review to trigger tests using our CI pipeline. If you need to make changes, please set the PR to a draft when pushing further commits until it's ready for review scion. We will get back to your with any further suggestions! +> **_NOTE:_** +> We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need +> to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. -## How fastplotlib works +3. Install `fastplotlib` in editable mode with developer dependencies -Fastplotlib uses the [`pygfx`](https://github.com/pygfx/pygfx) rendering engine to give users a high-level scientific -plotting library. Some degree of familiarity with [`pygfx`](https://github.com/pygfx/pygfx) or rendering engines may -be useful depending on the type of contribution you're working on. - -There are currently 2 major subpackages within `fastplotlib`, `layouts` and `graphics`. The user-facing public -class within `layouts` is `Figure`. A user is intended to create a `Figure`, and -then add *Graphics* to subplots within that `Figure`. +```bash +# install all extras in place +pip install -e ".[notebook,docs,tests]" +``` -### Graphics +> **_NOTE:_** +> If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any +> time to download the files stored on LFS -A `Graphic` is something that can be added to a `PlotArea` (described in detail in a later section). All the various -fastplotlib graphics, such as `ImageGraphic`, `ScatterGraphic`, etc. inherit from the `Graphic` base class in -`fastplotlib/graphics/_base.py`. It has a few properties that mostly wrap `pygfx` `WorldObject` properties and transforms. -These might change in the future (ex. `Graphic.position_x` etc.). +4. Add the upstream remote branch: -All graphics can be given a string name for the user's convenience. This allows graphics to be easily accessed from -plots, ex: `subplot["some_image"]`. +```bash +git remote add upstream https://github.com/fastplotlib/fastplotlib +``` -All graphics contain a `world_object` property which is just the `pygfx.WorldObject` that this graphic uses. Fastplotlib -keeps a *private* global dictionary of all `WorldObject` instances and users are only given a weakref proxy to this world object. -This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . -If you are curious or have more questions on garbage collection in fastplotlib you're welcome to post an issue :D. +At this point you have two remotes: `origin` (your fork) and `upstream` (the canonical version). You won't have permission to push to upstream (only `origin`), but +this make it easy to keep your `fastplotlib` up-to-date with the canonical version by pulling from upstream: `git pull upstream`. -#### Graphic properties +### Creating a new branch -Graphic properties are all evented, and internally we called these "graphic features". They are the various -aspects of a graphic that the user can change. -The "graphic features" subpackage can be found at `fastplotlib/graphics/_features`. As we can see this -is a private subpackage and never meant to be accessible to users.. +As mentioned previously, each feature in `fastplotlib` is worked on in a separate branch. This allows multiple people developing multiple features simultaneously, without interfering with each other's work. To create +your own branch, run the following from within your `fastplotlib` directory: -##### LineGraphic +```bash +# switch to the main branch on your local copy +git checkout main +# update your local copy from your fork +git pull origin main +# sync your local copy with upstream main +git pull upstream main +# update your fork's main branch with any changes from upstream +git push origin main +# create and switch to a new branch, where you'll work on your new feature +git checkout -b my_feature_branch +``` -For example let's look at `LineGraphic` in `fastplotlib/graphics/line.py`. Every graphic has a class variable called -`_features` which is a set of all graphic properties that are evented. It has the following evented properties: -`"data", "colors", "cmap", "thickness"` in addition to properties common to all graphics, such as `"name", "offset", "rotation", and "visible"` +After you have made changes on this branch, add and commit them when you are ready: -Now look at the constructor for the `LineGraphic` base class `PositionsGraphic`, it first creates an instance of `VertexPositions`. -This is a class that manages vertex positions buffer. It defines the line, and provides additional useful functionality. -For example, every time that the `data` is changed, the new data will be marked for upload to the GPU before the next draw. -In addition, event handlers will be called if any event handlers are registered. +```bash +# lint your code +black . -`VertexColors`behaves similarly, but it can perform additional parsing that can create the colors buffer from different -forms of user input. For example if a user runs: `line_graphic.colors = "blue"`, then `VertexColors.__setitem__()` will -create a buffer that corresponds to what `pygfx.Color` thinks is "blue". Users can also take advantage of fancy indexing, -ex: `line_graphics.colors[bool_array] = "red"` :smile: +# run tests from the repo root dir +WGPU_FORCE_OFFSCREEN=1 pytest tests/ -`LineGraphic` also has a `VertexCmap`, this manages the line `VertexColors` instance to parse colormaps, for example: -`line_graphic.cmap = "jet"` or even `line_graphic.cmap[50:] = "viridis"`. +# desktop examples +REGENERATE_SCREENSHOTS=1 pytest -v examples -`LineGraphic` also has a `thickness` property which is pretty simple, and `DeletedFeature` which is useful if you need -callbacks to indicate that the graphic has been deleted (for example, removing references to a graphic from a legend). +# notebook examples +FASTPLOTLIB_NB_TESTS=1 pytest --nbmake examples/notebooks/ -Other graphics have properties that are relevant to them, for example `ImageGraphic` has `cmap`, `vmin`, `vmax`, -properties unique to images. +# add your changed files, do not add any changes from the screenshot diff directory +git add my_changed_files -#### Selectors +# commit your changes +git commit -m "A one-line message explaining the changes made" -Selectors are a fairly new subpackage at `fastplotlib/graphics/selectors` which is likely to change significantly -after https://github.com/pygfx/pygfx/pull/665 . This subpackage contains selection tools, such as line selectors -(horizontal or vertical lines that can be moved), linear region selectors, and a primitive polygon drawing selection tool. -All selector tools inherit from `BaseSelector` in `graphics/selectors/_base_selector.py` but this is likely to change -after the aforementioned `Input` class PR in `pygfx` and after https://github.com/fastplotlib/fastplotlib/pull/413 . +# push to the remote origin +git push origin my_feature_branch +``` +> **_NOTE:_** If your contributions modify how visualizations _look_, see the [Tests in detail](#testing-) section at the very bottom. -### Layouts +### Contributing your changes back to `fastplotlib` -#### PlotArea +You can make any number of changes on your branch. Once you are happy with your changes, add tests to check that they run correctly and add +documentation to properly note your changes. +See below for details on how to [add tests](#adding-tests) and properly [document](#adding-documentation) your code. -This is the main base class within layouts. Subplots within a `Figure` and `Dock` areas within a `Subplot`, -inherit from `PlotArea`. +Now you are ready to make a Pull Request. You can open a pull request by clicking on the big `Compare & pull request` button that appears at the top of the `fastplotlib` repo +after pushing to your branch (see [here](https://intersect-training.org/collaborative-git/03-pr/index.html) for a tutorial). -`PlotArea` has the following key properties that allow it to be a "plot area" that can be used to view graphical objects: +> **_NOTE:_** Please make sure that you initially make your PR as a **draft** PR against the `main` branch. When you think the PR is ready, mark +> it for review to trigger tests using our CI pipeline. If you need to make changes, please set the PR back to a draft when pushing further +> commits until it's ready for review again. -* scene - instance of `pygfx.Scene` -* canvas - instance of `WgpuCanvas` -* renderer - instance of `pygfx.WgpuRenderer` -* viewport - instance of `pygfx.Viewport` -* camera - instance of `pygfx.PerspectiveCamera`, we always just use `PerspectiveCamera` and just set `camera.fov = 0` for orthographic projections -* controller - instance of `pygfx.Controller` +Your pull request should include the following: +- A summary including information on what you changed and why +- References to relevant issues or discussions +- Special notice to any portion of your changes where you have lingering questions (e.g., "was this the right way to implement this?") or +want reviewers to pay special attention to -Abstract method that must be implemented in subclasses: +Next, we will be notified of the pull request and will read it over. We will try to give and initial response quickly, and then do a longer in-depth +review, at which point you will probably need to respond to our comments, making changes as appropriate. We will then respond again, and proceed +in an iterative fashion until everyone is happy with the proposed changes. -* get_rect - musut return [x, y, width, height] that defines the viewport rect for this `PlotArea` +Once your changes are integrated, you will be added as a GitHub contributor and as one of the authors of the package. Thank you for being +apart of `fastplotlib`! -Properties specifically used by subplots in a Figure: +### Style Guide -* parent - A parent if relevant, used by individual `Subplots` in `Figure`, and by `Dock` which are "docked" subplots at the edges of a subplot. -* position - if a subplot within a Figure, it is the position of this subplot within the `Figure` +As far as code style, please adhere to the following guidelines: -Other important properties: +- Longer, descriptive names are preferred (e.g., `x` is not an appropriate name for a variable), especially for anything user-facing, +such as methods, attributes, or arguments +- Any public method or function must have complete type-annotated docstrings (see below for details). Hidden ones do not need to have +complete docstring, but they probably should. -* graphics - a tuple of weakref proxies to all `Graphics` within this `PlotArea`, users are only given weakref proxies to `Graphic` objects, all `Graphic` objects are stored in a private global dict. -* selectors - a tuple of weakref proxies to all selectors within this `PlotArea` -* legend - a tuple of weakref proxies to all legend graphics within this `PlotArea` -* name - plot areas are allowed to have names that the user can use for their convenience +### Releases -Important methods: +We create releases on Github, deploy on / distribute via [pypi](https://pypi.org/), and try to follow [semantic versioning](https://semver.org/): -* add_graphic - add a `Graphic` to the `PlotArea`, append to the end of the `PlotArea._graphics` list -* insert_graphic - insert a `Graphic` to the `PlotArea`, insert to a specific position of the `PlotArea._graphics` list -* remove_graphic - remove a graphic from the `Scene`, **does not delete it** -* delete_graphic - delete a graphic from the `PlotArea`, performs garbage collection -* clear - deletes all graphics from the `PlotArea` -* center_graphic - center camera w.r.t. a `Graphic` -* center_scene - center camera w.r.t. entire `Scene` -* auto_scale - Auto-scale the camera w.r.t to the `Scene` +> Given a version number MAJOR.MINOR.PATCH, increment the: +> 1. MAJOR version when you make incompatible API changes +> 2. MINOR version when you add functionality in a backward compatible manner +> 3. PATCH version when you make backward compatible bug fixes -In addition, `PlotArea` supports `__getitem__`, so you can do: `plot_area["graphic_name"]` to retrieve a `Graphic` by -name :smile: +To release a new version, we [create a GitHub release](https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository) with a new tag incrementing the version as described above. +Creating the GitHub release will trigger the deployment to pypi, via our `deploy` action (found in `.github/workflows/pypi-publish.yml`). +The built version will grab the version tag from the GitHub release, using [setuptools_scm](https://github.com/pypa/setuptools_scm). -You can also check if a `PlotArea` has certain graphics, ex: `"some_image_name" in plot_area`, or `graphic_instance in plot_area` +### Testing -#### Subplot +An integral part of our testing suite is not only to test that our code is working, but to also check that are plotting +library CI pipeline is producing things that "look visually correct". -This class inherits from `PlotArea` and `GraphicMethodsMixin`. +In order to do this, each example within the `examples` directory is run and an image of the canvas is taken and compared +with a ground-truth screenshot that we have manually inspected. Ground-truth images are stored using `git-lfs`. -`GraphicMethodsMixin` is a simple class that just has all the `add_` methods. It is autogenerated by a utility script like this: +The ground-truth images are located in: -```bash -python scripts/generate_add_methods.py +``` +examples/desktop/screenshots +examples/notebooks/screenshots ``` -Each `add_` method basically creates an instance of `Graphic`, adds it to the `Subplot`, and returns a weakref -proxy to the `Graphic`. - -Subplot has one property that is not in `PlotArea`: - -* docks: a `dict` of `PlotAreas` which are located at the "top", "right", "left", and "bottom" edges of a `Subplot`. By default their size is `0`. They are useful for putting things like histogram LUT tools. - -The key method in `Subplot` is an implementation of `get_rect` that returns the viewport rect for this subplot. - -#### Figure - -Now that we have understood `PlotArea` and `Subplot` we need a way for the user to create them! - -A `Figure` contains a grid of subplot and has methods such as `show()` to output the figure. -`Figure.__init__` basically does a lot of parsing of user arguments to determine how to create -the subplots. All subplots within a `Figure` share the same canvas and use different viewports to create the subplots. +The tests will produce slightly different imperceptible (to a human) results on different hardware when compared to the +ground-truth. A small RMSE tolerance has been chosen, `0.025` for most examples. If the output image and +ground-truth image are within that tolerance the test will pass. -## Tests in detail +Some feature development may require the ground-truth screenshots to be updated. In the event that your changes require +this, please do the following: -Backend tests are in `tests/`, in addition as a plotting library CI pipeline produces things that -"look visually correct". Each example within the `examples` dir is run and an image of the canvas -is taken and compared with a ground-truth screenshot that we have manually inspected. -Ground-truth image are stored using `git-lfs`. +1. Download the regenerated screenshots from the [`fastplotlib` GitHub Actions page](https://github.com/fastplotlib/fastplotlib/actions/workflows/screenshots.yml) for your specific PR -The ground-truth images are in: +2. Replace the screenshots in your local `fastplotlib` screenshots directories with those downloaded ``` examples/desktop/screenshots examples/notebooks/screenshots ``` -The tests will produce slightly different imperceptible (to a human) results on different hardware when compared to the -ground-truth. A small RMSE tolerance has been chosen, `0.025` for most examples. If the output image and -ground-truth image are within that tolerance the test will pass. - - -To run tests: +3. Commit your new screenshots and push them to your branch to get picked up by `git-lfs` ```bash -# tests basic backend functionality -WGPU_FORCE_OFFSCREEN=1 pytest -v -s tests/ +# add changes +git add examples/desktop/screenshots/ +git add examples/notebooks/screenshots -# desktop examples -pytest -v examples +# commit changes +git commit -m "update screenshots" -# notebook examples -FASTPLOTLIB_NB_TESTS=1 pytest --nbmake examples/notebooks/ +# push changes +git push origin my_feature_branch ``` -If your contribution modifies a ground-truth test screenshot then replace the ground-truth image along with your PR and -also notify us of this in the PR. Likewise, if your contribution requires a new test or new ground-truth then include -this new image in your PR. +#### Adding tests + +### Documentation + +#### Adding documentation + -You can create/regenerate ground-truths for the examples like this: -```bash -# desktop examples -REGENERATE_SCREENSHOTS=1 pytest -v examples/ -# notebook examples -FASTPLOTLIB_NB_TESTS=1 REGENERATE_SCREENSHOTS=1 pytest --nbmake examples/notebooks/image_widget_test.ipynb -``` -**Please only commit ground-truth images that correspond to your PR** since this will generate ground-truth images for -the entire test suite. diff --git a/docs/source/for_developers/developer_notes.rst b/docs/source/for_developers/developer_notes.rst new file mode 100644 index 000000000..e69de29bb From 72b523f72ff98b25c1045e31faab7728bf94202d Mon Sep 17 00:00:00 2001 From: Caitlin Date: Mon, 5 Aug 2024 16:46:07 -0400 Subject: [PATCH 2/8] start developer notes --- docs/source/developer_notes/README.md | 39 ++++++++++ docs/source/developer_notes/graphics.rst | 54 ++++++++++++++ docs/source/developer_notes/layouts.rst | 74 +++++++++++++++++++ .../source/for_developers/developer_notes.rst | 0 4 files changed, 167 insertions(+) create mode 100644 docs/source/developer_notes/README.md create mode 100644 docs/source/developer_notes/graphics.rst create mode 100644 docs/source/developer_notes/layouts.rst delete mode 100644 docs/source/for_developers/developer_notes.rst diff --git a/docs/source/developer_notes/README.md b/docs/source/developer_notes/README.md new file mode 100644 index 000000000..837d1a578 --- /dev/null +++ b/docs/source/developer_notes/README.md @@ -0,0 +1,39 @@ +# Introduction + +Welcome to the Developer Notes for `fastplotlib`. These notes aim to provide detailed and technical information +about the various modules, classes, and functions that make up this library, as well as guidelines on how to write +code that integrates nicely with our package. They are intended to help current and future developers understand +the design decisions, and functioning of the library. Furthermore, these notes aim to provide guidance on how to +modify, extend, and maintain the codebase. + +## Intended Audience + +These notes are primarily intended for the following groups: + +- **Current Developers**: The Developer Notes can serve as a comprehensive guide to understanding the library, making it easier to debug, modify and maintain the code. + +- **Future Developers**: These notes can help onboard new developers to the project, providing them with detailed explanations of the codebase and its underlying architecture. + +- **Contributors**: If you wish to contribute to the NeMoS project, the Developer Notes can provide a solid foundation of understanding, helping to ensure that your contributions align with the existing structure and design principles of the library. + +- **Advanced Users**: While the primary focus of these notes is on development, they might also be of interest to advanced users who want a deeper understanding of the library's functionality. + +Please note that these notes assume a certain level of programming knowledge. Familiarity with Python, object-oriented programming, and the NumPy and pygfx libraries would be beneficial when reading these notes. + +## Navigating the Developer Notes + +The Developer Notes are divided into sections, each focusing on a different component of the library. Each section provides an overview of the class or module, explains its role and functionality within the library, and offers a comprehensive guide to its classes and functions. +Typically, we will provide instructions on how to extend the existing modules. We generally advocate for the use of inheritance and encourage consistency with the existing codebase. In creating developer instructions, we follow the conventions outlined below: + +- **Must**: This denotes a requirement. Any method or function that fails to meet the requirement will not be merged. +- **Should**: This denotes a suggestion. Reasons should be provided if a suggestion is not followed. +- **May**: This denotes an option that, if implemented, could enhance the user/developer experience but can be overlooked if deemed unnecessary. + +## Interact with us + +If you're considering contributing to the library, first of all, welcome aboard! As a first step, we recommend that you read the [`CONTRIBUTING.md`](https://github.com/fastplotlib/fastplotlib/blob/main/CONTRIBUTING.md) guidelines. +These will help you understand how to interact with other contributors and how to submit your changes. + +If you have any questions or need further clarification on any of the topics covered in these notes, please don't hesitate to reach out to us. You can do so via the [discussion](https://github.com/fastplotlib/fastplotlib/discussions/landing) forum on GitHub. + +We're looking forward to your contributions and to answering any questions you might have! \ No newline at end of file diff --git a/docs/source/developer_notes/graphics.rst b/docs/source/developer_notes/graphics.rst new file mode 100644 index 000000000..4dc54efe3 --- /dev/null +++ b/docs/source/developer_notes/graphics.rst @@ -0,0 +1,54 @@ +### Graphics + +A `Graphic` is something that can be added to a `PlotArea` (described in detail in a later section). All the various +fastplotlib graphics, such as `ImageGraphic`, `ScatterGraphic`, etc. inherit from the `Graphic` base class in +`fastplotlib/graphics/_base.py`. It has a few properties that mostly wrap `pygfx` `WorldObject` properties and transforms. +These might change in the future (ex. `Graphic.position_x` etc.). + +All graphics can be given a string name for the user's convenience. This allows graphics to be easily accessed from +plots, ex: `subplot["some_image"]`. + +All graphics contain a `world_object` property which is just the `pygfx.WorldObject` that this graphic uses. Fastplotlib +keeps a *private* global dictionary of all `WorldObject` instances and users are only given a weakref proxy to this world object. +This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . +If you are curious or have more questions on garbage collection in fastplotlib you're welcome to post an issue :D. + +#### Graphic properties + +Graphic properties are all evented, and internally we called these "graphic features". They are the various +aspects of a graphic that the user can change. +The "graphic features" subpackage can be found at `fastplotlib/graphics/_features`. As we can see this +is a private subpackage and never meant to be accessible to users.. + +##### LineGraphic + +For example let's look at `LineGraphic` in `fastplotlib/graphics/line.py`. Every graphic has a class variable called +`_features` which is a set of all graphic properties that are evented. It has the following evented properties: +`"data", "colors", "cmap", "thickness"` in addition to properties common to all graphics, such as `"name", "offset", "rotation", and "visible"` + +Now look at the constructor for the `LineGraphic` base class `PositionsGraphic`, it first creates an instance of `VertexPositions`. +This is a class that manages vertex positions buffer. It defines the line, and provides additional useful functionality. +For example, every time that the `data` is changed, the new data will be marked for upload to the GPU before the next draw. +In addition, event handlers will be called if any event handlers are registered. + +`VertexColors`behaves similarly, but it can perform additional parsing that can create the colors buffer from different +forms of user input. For example if a user runs: `line_graphic.colors = "blue"`, then `VertexColors.__setitem__()` will +create a buffer that corresponds to what `pygfx.Color` thinks is "blue". Users can also take advantage of fancy indexing, +ex: `line_graphics.colors[bool_array] = "red"` :smile: + +`LineGraphic` also has a `VertexCmap`, this manages the line `VertexColors` instance to parse colormaps, for example: +`line_graphic.cmap = "jet"` or even `line_graphic.cmap[50:] = "viridis"`. + +`LineGraphic` also has a `thickness` property which is pretty simple, and `DeletedFeature` which is useful if you need +callbacks to indicate that the graphic has been deleted (for example, removing references to a graphic from a legend). + +Other graphics have properties that are relevant to them, for example `ImageGraphic` has `cmap`, `vmin`, `vmax`, +properties unique to images. + +#### Selectors + +Selectors are a fairly new subpackage at `fastplotlib/graphics/selectors` which is likely to change significantly +after https://github.com/pygfx/pygfx/pull/665 . This subpackage contains selection tools, such as line selectors +(horizontal or vertical lines that can be moved), linear region selectors, and a primitive polygon drawing selection tool. +All selector tools inherit from `BaseSelector` in `graphics/selectors/_base_selector.py` but this is likely to change +after the aforementioned `Input` class PR in `pygfx` and after https://github.com/fastplotlib/fastplotlib/pull/413 . \ No newline at end of file diff --git a/docs/source/developer_notes/layouts.rst b/docs/source/developer_notes/layouts.rst new file mode 100644 index 000000000..973f3b786 --- /dev/null +++ b/docs/source/developer_notes/layouts.rst @@ -0,0 +1,74 @@ +### Layouts + +#### PlotArea + +This is the main base class within layouts. Subplots within a `Figure` and `Dock` areas within a `Subplot`, +inherit from `PlotArea`. + +`PlotArea` has the following key properties that allow it to be a "plot area" that can be used to view graphical objects: + +* scene - instance of `pygfx.Scene` +* canvas - instance of `WgpuCanvas` +* renderer - instance of `pygfx.WgpuRenderer` +* viewport - instance of `pygfx.Viewport` +* camera - instance of `pygfx.PerspectiveCamera`, we always just use `PerspectiveCamera` and just set `camera.fov = 0` for orthographic projections +* controller - instance of `pygfx.Controller` + +Abstract method that must be implemented in subclasses: + +* get_rect - musut return [x, y, width, height] that defines the viewport rect for this `PlotArea` + +Properties specifically used by subplots in a Figure: + +* parent - A parent if relevant, used by individual `Subplots` in `Figure`, and by `Dock` which are "docked" subplots at the edges of a subplot. +* position - if a subplot within a Figure, it is the position of this subplot within the `Figure` + +Other important properties: + +* graphics - a tuple of weakref proxies to all `Graphics` within this `PlotArea`, users are only given weakref proxies to `Graphic` objects, all `Graphic` objects are stored in a private global dict. +* selectors - a tuple of weakref proxies to all selectors within this `PlotArea` +* legend - a tuple of weakref proxies to all legend graphics within this `PlotArea` +* name - plot areas are allowed to have names that the user can use for their convenience + +Important methods: + +* add_graphic - add a `Graphic` to the `PlotArea`, append to the end of the `PlotArea._graphics` list +* insert_graphic - insert a `Graphic` to the `PlotArea`, insert to a specific position of the `PlotArea._graphics` list +* remove_graphic - remove a graphic from the `Scene`, **does not delete it** +* delete_graphic - delete a graphic from the `PlotArea`, performs garbage collection +* clear - deletes all graphics from the `PlotArea` +* center_graphic - center camera w.r.t. a `Graphic` +* center_scene - center camera w.r.t. entire `Scene` +* auto_scale - Auto-scale the camera w.r.t to the `Scene` + +In addition, `PlotArea` supports `__getitem__`, so you can do: `plot_area["graphic_name"]` to retrieve a `Graphic` by +name :smile: + +You can also check if a `PlotArea` has certain graphics, ex: `"some_image_name" in plot_area`, or `graphic_instance in plot_area` + +#### Subplot + +This class inherits from `PlotArea` and `GraphicMethodsMixin`. + +`GraphicMethodsMixin` is a simple class that just has all the `add_` methods. It is autogenerated by a utility script like this: + +```bash +python scripts/generate_add_methods.py +``` + +Each `add_` method basically creates an instance of `Graphic`, adds it to the `Subplot`, and returns a weakref +proxy to the `Graphic`. + +Subplot has one property that is not in `PlotArea`: + +* docks: a `dict` of `PlotAreas` which are located at the "top", "right", "left", and "bottom" edges of a `Subplot`. By default their size is `0`. They are useful for putting things like histogram LUT tools. + +The key method in `Subplot` is an implementation of `get_rect` that returns the viewport rect for this subplot. + +#### Figure + +Now that we have understood `PlotArea` and `Subplot` we need a way for the user to create them! + +A `Figure` contains a grid of subplot and has methods such as `show()` to output the figure. +`Figure.__init__` basically does a lot of parsing of user arguments to determine how to create +the subplots. All subplots within a `Figure` share the same canvas and use different viewports to create the subplots. \ No newline at end of file diff --git a/docs/source/for_developers/developer_notes.rst b/docs/source/for_developers/developer_notes.rst deleted file mode 100644 index e69de29bb..000000000 From 9c55b9d233548a47acd170e9c0bf47a4eadc430e Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 6 Aug 2024 11:42:08 -0400 Subject: [PATCH 3/8] more contributing updates --- CONTRIBUTING.md | 107 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 94 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c9e19ae48..e2dd90160 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,11 +7,13 @@ from everyone! :smile: This guide explains how to contribute: if you have questions about the process, please reach out on [GitHub Discussions](https://github.com/fastplotlib/fastplotlib/discussions). +If you are already familiar with contributing to open-source software packages, please check out the [quick guide](#contributing-quick-guide)! + ## General Guidelines Developers are encouraged to contribute to various areas of development. This could include the addition of new features (e.g. -graphics or selector tools), bug fixes, or the addition of new examples to the [examples gallery](https://fastplotlib.readthedocs.io/en/latest/_gallery/index.html) . Enhancements to documentation and the overall readability of the -code are also greatly appreciated. +graphics or selector tools), bug fixes, or the addition of new examples to the [examples gallery](https://fastplotlib.readthedocs.io/en/latest/_gallery/index.html). +Enhancements to documentation and the overall readability of the code are also greatly appreciated. Feel free to work on any section of the code that you believe you can improve. More importantly, remember to thoroughly test all your classes and functions, and to provide clear, detailed comments within your code. This not only aids others in using the library, @@ -44,15 +46,15 @@ You will need a local installation `fastplotlib` which keeps up-to-date with any 2. Clone the repo. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. +> **_NOTE:_** +> We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need +> to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. + ```bash git clone https://github.com/YOUR_ACCOUNT/fastplotlib.git cd fastplotlib ``` -> **_NOTE:_** -> We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need -> to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. - 3. Install `fastplotlib` in editable mode with developer dependencies ```bash @@ -101,7 +103,7 @@ black . WGPU_FORCE_OFFSCREEN=1 pytest tests/ # desktop examples -REGENERATE_SCREENSHOTS=1 pytest -v examples +pytest -v examples # notebook examples FASTPLOTLIB_NB_TESTS=1 pytest --nbmake examples/notebooks/ @@ -115,7 +117,7 @@ git commit -m "A one-line message explaining the changes made" # push to the remote origin git push origin my_feature_branch ``` -> **_NOTE:_** If your contributions modify how visualizations _look_, see the [Tests in detail](#testing-) section at the very bottom. +> **_NOTE:_** If your contributions modify how visualizations _look_, see the [Tests in detail](#testing-details) section at the very bottom. ### Contributing your changes back to `fastplotlib` @@ -123,12 +125,12 @@ You can make any number of changes on your branch. Once you are happy with your documentation to properly note your changes. See below for details on how to [add tests](#adding-tests) and properly [document](#adding-documentation) your code. -Now you are ready to make a Pull Request. You can open a pull request by clicking on the big `Compare & pull request` button that appears at the top of the `fastplotlib` repo +Now you are ready to make a Pull Request. You can open a pull request by clicking on the big `Compare & pull request` button that appears at the top of the `fastplotlib` repo after pushing to your branch (see [here](https://intersect-training.org/collaborative-git/03-pr/index.html) for a tutorial). > **_NOTE:_** Please make sure that you initially make your PR as a **draft** PR against the `main` branch. When you think the PR is ready, mark > it for review to trigger tests using our CI pipeline. If you need to make changes, please set the PR back to a draft when pushing further -> commits until it's ready for review again. +> commits until it is ready for review again. Your pull request should include the following: - A summary including information on what you changed and why @@ -140,7 +142,7 @@ Next, we will be notified of the pull request and will read it over. We will try review, at which point you will probably need to respond to our comments, making changes as appropriate. We will then respond again, and proceed in an iterative fashion until everyone is happy with the proposed changes. -Once your changes are integrated, you will be added as a GitHub contributor and as one of the authors of the package. Thank you for being +Once your changes are integrated, you will be added as a GitHub contributor. Thank you for being apart of `fastplotlib`! ### Style Guide @@ -154,7 +156,7 @@ complete docstring, but they probably should. ### Releases -We create releases on Github, deploy on / distribute via [pypi](https://pypi.org/), and try to follow [semantic versioning](https://semver.org/): +We create releases on GitHub, deploy on / distribute via [pypi](https://pypi.org/), and try to follow [semantic versioning](https://semver.org/): > Given a version number MAJOR.MINOR.PATCH, increment the: > 1. MAJOR version when you make incompatible API changes @@ -167,6 +169,8 @@ The built version will grab the version tag from the GitHub release, using [setu ### Testing +#### Testing Details + An integral part of our testing suite is not only to test that our code is working, but to also check that are plotting library CI pipeline is producing things that "look visually correct". @@ -201,7 +205,7 @@ examples/notebooks/screenshots ```bash # add changes git add examples/desktop/screenshots/ -git add examples/notebooks/screenshots +git add examples/notebooks/screenshots/ # commit changes git commit -m "update screenshots" @@ -212,11 +216,88 @@ git push origin my_feature_branch #### Adding tests +Depending on the type of contribution you are making, new tests will need to be added to the repository. Unit tests for testing underlying functionality such as buffer managers, figure instantiation, and +more can be found in the `/tests` directory. However, we also test all of our desktop examples as well. + +If you are adding a new example to the library, you will need to add to comments to the top of your `.py` file in order to make sure it is both tested and added to the gallery. + +```python +# test_example = true +# sphinx_gallery_pygfx_docs = 'screenshot' +``` + ### Documentation +Documentation is a crucial part of open-source software and greatly influences the ability to use a codebase. As such, it is imperative that any new changes are +properly documented as outlined below. + +We use [`sphinx`](https://www.sphinx-doc.org/en/master/) for generating our documentation. In addition to this, we also use the [`sphinx-gallery`](https://sphinx-gallery.github.io/stable/index.html) +extension to build our examples gallery. + +If you would like to build the documentation locally: + +```bash +cd docs +# regenerate the api guide +python source/generate_api.py + +# build locally +make html +``` + #### Adding documentation +All public-facing functions and classes should have complete docstrings, which start with a one-line short summary of the function, +a medium-length description of the function / class and what it does, and a complete description of all arguments and return values. +Docstrings should be relatively short, providing the information necessary for a user to use the code. + +Private functions and classes should have sufficient explanation that other developers know what the function / class does and how to use it, +but do not need to be as extensive. + +We follow the [numpydoc](https://numpydoc.readthedocs.io/en/latest/) conventions for docstring structure. + +### Contributing Quick Guide + +This section is a brief introduction to how to contribute to `fastplotlib`. It is intended for individuals who have prior experience with contributing +to open source software packages. + +> **_NOTE:_** +> We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need +> to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. + +1) Fork and clone the repo + +2) Install locally with developer dependencies + +```bash +# after cloning +cd fastplotlib +# install dev dependencies +pip install -e ".[tests, docs, notebook]" +``` + +3) Check out a feature branch from `main` + +4) Lint codebase and make sure tests pass + +```bash +# lint codebase +black . + +# run tests +# backend tests +WGPU_FORCE_OFFSCREEN=1 pytest tests/ + +# desktop examples +pytest -v examples + +# notebook examples +FASTPLOTLIB_NB_TESTS=1 pytest --nbmake examples/notebooks/ +``` + +5) Update screenshots if necessary ([see testing](#testing-details)) +6) Push and open a draft PR against `main` From bbdbfe0a66166be4256d24af12b390a67d5afb0e Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 6 Aug 2024 15:31:56 -0400 Subject: [PATCH 4/8] start to make developer notes --- CONTRIBUTING.md | 15 ++-- docs/source/developer_notes/graphics.rst | 85 ++++++++++++------- docs/source/developer_notes/index.rst | 9 ++ .../developer_notes/{README.md => intro.rst} | 16 ++-- docs/source/index.rst | 3 +- 5 files changed, 84 insertions(+), 44 deletions(-) create mode 100644 docs/source/developer_notes/index.rst rename docs/source/developer_notes/{README.md => intro.rst} (85%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e2dd90160..84422f5c7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -7,7 +7,8 @@ from everyone! :smile: This guide explains how to contribute: if you have questions about the process, please reach out on [GitHub Discussions](https://github.com/fastplotlib/fastplotlib/discussions). -If you are already familiar with contributing to open-source software packages, please check out the [quick guide](#contributing-quick-guide)! +> **_NOTE:_** If you are already familiar with contributing to open-source software packages, +> please check out the [quick guide](#contributing-quick-guide)! ## General Guidelines @@ -46,8 +47,7 @@ You will need a local installation `fastplotlib` which keeps up-to-date with any 2. Clone the repo. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. -> **_NOTE:_** -> We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need +> **_NOTE:_** We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need > to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. ```bash @@ -62,8 +62,7 @@ cd fastplotlib pip install -e ".[notebook,docs,tests]" ``` -> **_NOTE:_** -> If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any +> **_NOTE:_** If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any > time to download the files stored on LFS 4. Add the upstream remote branch: @@ -83,12 +82,16 @@ your own branch, run the following from within your `fastplotlib` directory: ```bash # switch to the main branch on your local copy git checkout main + # update your local copy from your fork git pull origin main + # sync your local copy with upstream main git pull upstream main + # update your fork's main branch with any changes from upstream git push origin main + # create and switch to a new branch, where you'll work on your new feature git checkout -b my_feature_branch ``` @@ -117,7 +120,7 @@ git commit -m "A one-line message explaining the changes made" # push to the remote origin git push origin my_feature_branch ``` -> **_NOTE:_** If your contributions modify how visualizations _look_, see the [Tests in detail](#testing-details) section at the very bottom. +> **_NOTE:_** If your contributions modify how visualizations _look_, see the [Testing details](#testing-details) section at the very bottom. ### Contributing your changes back to `fastplotlib` diff --git a/docs/source/developer_notes/graphics.rst b/docs/source/developer_notes/graphics.rst index 4dc54efe3..958deb75c 100644 --- a/docs/source/developer_notes/graphics.rst +++ b/docs/source/developer_notes/graphics.rst @@ -1,54 +1,77 @@ -### Graphics +Graphics +======== -A `Graphic` is something that can be added to a `PlotArea` (described in detail in a later section). All the various -fastplotlib graphics, such as `ImageGraphic`, `ScatterGraphic`, etc. inherit from the `Graphic` base class in -`fastplotlib/graphics/_base.py`. It has a few properties that mostly wrap `pygfx` `WorldObject` properties and transforms. -These might change in the future (ex. `Graphic.position_x` etc.). + +A ``Graphic`` is something that can be added to a ``PlotArea`` (described in detail in a later section). All the various +fastplotlib graphics, such as ``ImageGraphic``, ``ScatterGraphic``, etc. inherit from the ``Graphic`` base class in +``fastplotlib/graphics/_base.py``. It has a few properties that mostly wrap ``pygfx`` ``WorldObject`` properties and transforms. +These might change in the future (ex. ``Graphic.position_x`` etc.). + +``` +Graphic +| +├─ ImageGraphic +│ +├─ TextGraphic +│ +├─ PositionsGraphic +│ │ +│ ├─ LineGraphic +│ │ +│ └─ ScatterGraphic +│ +└─ GraphicCollection + │ + └─ LineCollection + │ + └─ LineStack + +``` All graphics can be given a string name for the user's convenience. This allows graphics to be easily accessed from -plots, ex: `subplot["some_image"]`. +plots, ex: ``subplot["some_image"]``. -All graphics contain a `world_object` property which is just the `pygfx.WorldObject` that this graphic uses. Fastplotlib -keeps a *private* global dictionary of all `WorldObject` instances and users are only given a weakref proxy to this world object. +All graphics contain a ``world_object`` property which is just the ``pygfx.WorldObject`` that this graphic uses. Fastplotlib +keeps a *private* global dictionary of all ``WorldObject`` instances and users are only given a weakref proxy to this world object. This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . -If you are curious or have more questions on garbage collection in fastplotlib you're welcome to post an issue :D. +If you are curious or have more questions on garbage collection in `fastplotlib` you're welcome to post an issue :D. -#### Graphic properties +Graphic Properties +------------------ -Graphic properties are all evented, and internally we called these "graphic features". They are the various +Graphic properties are all evented, and internally we call these "graphic features". They are the various aspects of a graphic that the user can change. -The "graphic features" subpackage can be found at `fastplotlib/graphics/_features`. As we can see this -is a private subpackage and never meant to be accessible to users.. - -##### LineGraphic +The "graphic features" subpackage can be found at ``fastplotlib/graphics/_features``. As we can see this +is a private subpackage and never meant to be accessible to users. -For example let's look at `LineGraphic` in `fastplotlib/graphics/line.py`. Every graphic has a class variable called -`_features` which is a set of all graphic properties that are evented. It has the following evented properties: -`"data", "colors", "cmap", "thickness"` in addition to properties common to all graphics, such as `"name", "offset", "rotation", and "visible"` +For example let's look at ``LineGraphic`` in ``fastplotlib/graphics/line.py``. Every graphic has a class variable called +``_features`` which is a set of all graphic properties that are evented. It has the following evented properties: +``"data", "colors", "cmap", "thickness"`` in addition to properties common to all graphics, such as ``"name", "offset", "rotation", and "visible"`` -Now look at the constructor for the `LineGraphic` base class `PositionsGraphic`, it first creates an instance of `VertexPositions`. +Now look at the constructor for the ``LineGraphic`` base class ``PositionsGraphic``, it first creates an instance of ``VertexPositions``. This is a class that manages vertex positions buffer. It defines the line, and provides additional useful functionality. -For example, every time that the `data` is changed, the new data will be marked for upload to the GPU before the next draw. +For example, every time that the ``data`` is changed, the new data will be marked for upload to the GPU before the next draw. In addition, event handlers will be called if any event handlers are registered. -`VertexColors`behaves similarly, but it can perform additional parsing that can create the colors buffer from different -forms of user input. For example if a user runs: `line_graphic.colors = "blue"`, then `VertexColors.__setitem__()` will +``VertexColors``behaves similarly, but it can perform additional parsing that can create the colors buffer from different +forms of user input. For example if a user runs: ``line_graphic.colors = "blue"``, then ``VertexColors.__setitem__()`` will create a buffer that corresponds to what `pygfx.Color` thinks is "blue". Users can also take advantage of fancy indexing, -ex: `line_graphics.colors[bool_array] = "red"` :smile: +ex: ``line_graphics.colors[bool_array] = "red"`` :smile: -`LineGraphic` also has a `VertexCmap`, this manages the line `VertexColors` instance to parse colormaps, for example: -`line_graphic.cmap = "jet"` or even `line_graphic.cmap[50:] = "viridis"`. +``LineGraphic`` also has a ``VertexCmap``, this manages the line ``VertexColors`` instance to parse colormaps, for example: +``line_graphic.cmap = "jet"`` or even ``line_graphic.cmap[50:] = "viridis"``. -`LineGraphic` also has a `thickness` property which is pretty simple, and `DeletedFeature` which is useful if you need +``LineGraphic`` also has a ``thickness`` property which is pretty simple, and ``DeletedFeature`` which is useful if you need callbacks to indicate that the graphic has been deleted (for example, removing references to a graphic from a legend). -Other graphics have properties that are relevant to them, for example `ImageGraphic` has `cmap`, `vmin`, `vmax`, +Other graphics have properties that are relevant to them, for example ``ImageGraphic`` has ``cmap``, ``vmin``, ``vmax``, properties unique to images. -#### Selectors +Selectors +--------- -Selectors are a fairly new subpackage at `fastplotlib/graphics/selectors` which is likely to change significantly +Selectors are a fairly new subpackage at ``fastplotlib/graphics/selectors`` which is likely to change significantly after https://github.com/pygfx/pygfx/pull/665 . This subpackage contains selection tools, such as line selectors (horizontal or vertical lines that can be moved), linear region selectors, and a primitive polygon drawing selection tool. -All selector tools inherit from `BaseSelector` in `graphics/selectors/_base_selector.py` but this is likely to change -after the aforementioned `Input` class PR in `pygfx` and after https://github.com/fastplotlib/fastplotlib/pull/413 . \ No newline at end of file +All selector tools inherit from ``BaseSelector`` in ``graphics/selectors/_base_selector.py`` but this is likely to change +after the aforementioned ``Input`` class PR in ``pygfx`` and after https://github.com/fastplotlib/fastplotlib/pull/413 . \ No newline at end of file diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst new file mode 100644 index 000000000..0094bee73 --- /dev/null +++ b/docs/source/developer_notes/index.rst @@ -0,0 +1,9 @@ +Developer Notes +*************** + +.. toctree:: + :maxdepth: 1 + + intro + graphics + layouts \ No newline at end of file diff --git a/docs/source/developer_notes/README.md b/docs/source/developer_notes/intro.rst similarity index 85% rename from docs/source/developer_notes/README.md rename to docs/source/developer_notes/intro.rst index 837d1a578..d9bed2e97 100644 --- a/docs/source/developer_notes/README.md +++ b/docs/source/developer_notes/intro.rst @@ -1,4 +1,5 @@ -# Introduction +`fastplotlib` Developer Notes +============================= Welcome to the Developer Notes for `fastplotlib`. These notes aim to provide detailed and technical information about the various modules, classes, and functions that make up this library, as well as guidelines on how to write @@ -6,7 +7,8 @@ code that integrates nicely with our package. They are intended to help current the design decisions, and functioning of the library. Furthermore, these notes aim to provide guidance on how to modify, extend, and maintain the codebase. -## Intended Audience +Intended Audience +----------------- These notes are primarily intended for the following groups: @@ -14,13 +16,14 @@ These notes are primarily intended for the following groups: - **Future Developers**: These notes can help onboard new developers to the project, providing them with detailed explanations of the codebase and its underlying architecture. -- **Contributors**: If you wish to contribute to the NeMoS project, the Developer Notes can provide a solid foundation of understanding, helping to ensure that your contributions align with the existing structure and design principles of the library. +- **Contributors**: If you wish to contribute to the `fastplotlib` project, the Developer Notes can provide a solid foundation of understanding, helping to ensure that your contributions align with the existing structure and design principles of the library. - **Advanced Users**: While the primary focus of these notes is on development, they might also be of interest to advanced users who want a deeper understanding of the library's functionality. Please note that these notes assume a certain level of programming knowledge. Familiarity with Python, object-oriented programming, and the NumPy and pygfx libraries would be beneficial when reading these notes. -## Navigating the Developer Notes +Navigating the Developer Notes +------------------------------ The Developer Notes are divided into sections, each focusing on a different component of the library. Each section provides an overview of the class or module, explains its role and functionality within the library, and offers a comprehensive guide to its classes and functions. Typically, we will provide instructions on how to extend the existing modules. We generally advocate for the use of inheritance and encourage consistency with the existing codebase. In creating developer instructions, we follow the conventions outlined below: @@ -29,11 +32,12 @@ Typically, we will provide instructions on how to extend the existing modules. W - **Should**: This denotes a suggestion. Reasons should be provided if a suggestion is not followed. - **May**: This denotes an option that, if implemented, could enhance the user/developer experience but can be overlooked if deemed unnecessary. -## Interact with us +Interact with us +---------------- If you're considering contributing to the library, first of all, welcome aboard! As a first step, we recommend that you read the [`CONTRIBUTING.md`](https://github.com/fastplotlib/fastplotlib/blob/main/CONTRIBUTING.md) guidelines. These will help you understand how to interact with other contributors and how to submit your changes. If you have any questions or need further clarification on any of the topics covered in these notes, please don't hesitate to reach out to us. You can do so via the [discussion](https://github.com/fastplotlib/fastplotlib/discussions/landing) forum on GitHub. -We're looking forward to your contributions and to answering any questions you might have! \ No newline at end of file +We're looking forward to your contributions and to answering any questions you might have! diff --git a/docs/source/index.rst b/docs/source/index.rst index cf752a83b..ed36a2dbd 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,10 +3,11 @@ Welcome to fastplotlib's documentation! .. toctree:: :caption: User Guide - :maxdepth: 2 + :maxdepth: 1 Guide GPU Info + Developer Notes .. toctree:: :maxdepth: 1 From e0b9ed5d08d8b541e9501e7f6a0f31200288b739 Mon Sep 17 00:00:00 2001 From: Caitlin Date: Tue, 6 Aug 2024 16:57:37 -0400 Subject: [PATCH 5/8] reorganize some --- docs/source/developer_notes/graphics.rst | 60 +++++++++++++----------- docs/source/developer_notes/index.rst | 42 ++++++++++++++++- docs/source/developer_notes/intro.rst | 43 ----------------- 3 files changed, 74 insertions(+), 71 deletions(-) delete mode 100644 docs/source/developer_notes/intro.rst diff --git a/docs/source/developer_notes/graphics.rst b/docs/source/developer_notes/graphics.rst index 958deb75c..508d73751 100644 --- a/docs/source/developer_notes/graphics.rst +++ b/docs/source/developer_notes/graphics.rst @@ -2,31 +2,31 @@ Graphics ======== -A ``Graphic`` is something that can be added to a ``PlotArea`` (described in detail in a later section). All the various +A ``Graphic`` is something that can be added to a ``PlotArea`` (described in detail in the layouts section). All the various fastplotlib graphics, such as ``ImageGraphic``, ``ScatterGraphic``, etc. inherit from the ``Graphic`` base class in ``fastplotlib/graphics/_base.py``. It has a few properties that mostly wrap ``pygfx`` ``WorldObject`` properties and transforms. -These might change in the future (ex. ``Graphic.position_x`` etc.). - -``` -Graphic -| -├─ ImageGraphic -│ -├─ TextGraphic -│ -├─ PositionsGraphic -│ │ -│ ├─ LineGraphic -│ │ -│ └─ ScatterGraphic -│ -└─ GraphicCollection + +.. code-block:: rst + + Graphic + │ + ├─ ImageGraphic │ - └─ LineCollection + ├─ TextGraphic + │ + ├─ PositionsGraphic + │ │ + │ ├─ LineGraphic + │ │ + │ └─ ScatterGraphic + │ + └─ GraphicCollection │ - └─ LineStack + └─ LineCollection + │ + └─ LineStack -``` +.. All graphics can be given a string name for the user's convenience. This allows graphics to be easily accessed from plots, ex: ``subplot["some_image"]``. @@ -36,6 +36,8 @@ keeps a *private* global dictionary of all ``WorldObject`` instances and users a This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . If you are curious or have more questions on garbage collection in `fastplotlib` you're welcome to post an issue :D. +## add notes on graphic collections + Graphic Properties ------------------ @@ -67,11 +69,15 @@ callbacks to indicate that the graphic has been deleted (for example, removing r Other graphics have properties that are relevant to them, for example ``ImageGraphic`` has ``cmap``, ``vmin``, ``vmax``, properties unique to images. -Selectors ---------- +Contributors Guidelines +----------------------- + +**Implementing New Graphics** + +- **Must** inherit from the superclass ``Graphic`` + +- **May** inherit from intermediate classes such as ``GraphicCollection`` or ``PositionsGraphic`` depending on + the type of graphic you are trying to implement + + -Selectors are a fairly new subpackage at ``fastplotlib/graphics/selectors`` which is likely to change significantly -after https://github.com/pygfx/pygfx/pull/665 . This subpackage contains selection tools, such as line selectors -(horizontal or vertical lines that can be moved), linear region selectors, and a primitive polygon drawing selection tool. -All selector tools inherit from ``BaseSelector`` in ``graphics/selectors/_base_selector.py`` but this is likely to change -after the aforementioned ``Input`` class PR in ``pygfx`` and after https://github.com/fastplotlib/fastplotlib/pull/413 . \ No newline at end of file diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst index 0094bee73..34f1eba0e 100644 --- a/docs/source/developer_notes/index.rst +++ b/docs/source/developer_notes/index.rst @@ -1,9 +1,49 @@ Developer Notes *************** +Welcome to the Developer Notes for `fastplotlib`. These notes aim to provide detailed and technical information +about the various modules, classes, and functions that make up this library, as well as guidelines on how to write +code that integrates nicely with our package. They are intended to help current and future developers understand +the design decisions, and functioning of the library. Furthermore, these notes aim to provide guidance on how to +modify, extend, and maintain the codebase. + +Intended Audience +----------------- + +These notes are primarily intended for the following groups: + +- **Current Developers**: The Developer Notes can serve as a comprehensive guide to understanding the library, making it easier to debug, modify and maintain the code. + +- **Future Developers**: These notes can help onboard new developers to the project, providing them with detailed explanations of the codebase and its underlying architecture. + +- **Contributors**: If you wish to contribute to the `fastplotlib` project, the Developer Notes can provide a solid foundation of understanding, helping to ensure that your contributions align with the existing structure and design principles of the library. + +- **Advanced Users**: While the primary focus of these notes is on development, they might also be of interest to advanced users who want a deeper understanding of the library's functionality. + +Please note that these notes assume a certain level of programming knowledge. Familiarity with Python, object-oriented programming, and the NumPy and pygfx libraries would be beneficial when reading these notes. + +Navigating the Developer Notes +------------------------------ + +The Developer Notes are divided into sections, each focusing on a different component of the library. Each section provides an overview of the class or module, explains its role and functionality within the library, and offers a comprehensive guide to its classes and functions. +Typically, we will provide instructions on how to extend the existing modules. We generally advocate for the use of inheritance and encourage consistency with the existing codebase. In creating developer instructions, we follow the conventions outlined below: + +- **Must**: This denotes a requirement. Any method or function that fails to meet the requirement will not be merged. +- **Should**: This denotes a suggestion. Reasons should be provided if a suggestion is not followed. +- **May**: This denotes an option that, if implemented, could enhance the user/developer experience but can be overlooked if deemed unnecessary. + +Interact with us +---------------- + +If you're considering contributing to the library, first of all, welcome aboard! As a first step, we recommend that you read the [`CONTRIBUTING.md`](https://github.com/fastplotlib/fastplotlib/blob/main/CONTRIBUTING.md) guidelines. +These will help you understand how to interact with other contributors and how to submit your changes. + +If you have any questions or need further clarification on any of the topics covered in these notes, please don't hesitate to reach out to us. You can do so via the [discussion](https://github.com/fastplotlib/fastplotlib/discussions/landing) forum on GitHub. + +We're looking forward to your contributions and to answering any questions you might have! + .. toctree:: :maxdepth: 1 - intro graphics layouts \ No newline at end of file diff --git a/docs/source/developer_notes/intro.rst b/docs/source/developer_notes/intro.rst deleted file mode 100644 index d9bed2e97..000000000 --- a/docs/source/developer_notes/intro.rst +++ /dev/null @@ -1,43 +0,0 @@ -`fastplotlib` Developer Notes -============================= - -Welcome to the Developer Notes for `fastplotlib`. These notes aim to provide detailed and technical information -about the various modules, classes, and functions that make up this library, as well as guidelines on how to write -code that integrates nicely with our package. They are intended to help current and future developers understand -the design decisions, and functioning of the library. Furthermore, these notes aim to provide guidance on how to -modify, extend, and maintain the codebase. - -Intended Audience ------------------ - -These notes are primarily intended for the following groups: - -- **Current Developers**: The Developer Notes can serve as a comprehensive guide to understanding the library, making it easier to debug, modify and maintain the code. - -- **Future Developers**: These notes can help onboard new developers to the project, providing them with detailed explanations of the codebase and its underlying architecture. - -- **Contributors**: If you wish to contribute to the `fastplotlib` project, the Developer Notes can provide a solid foundation of understanding, helping to ensure that your contributions align with the existing structure and design principles of the library. - -- **Advanced Users**: While the primary focus of these notes is on development, they might also be of interest to advanced users who want a deeper understanding of the library's functionality. - -Please note that these notes assume a certain level of programming knowledge. Familiarity with Python, object-oriented programming, and the NumPy and pygfx libraries would be beneficial when reading these notes. - -Navigating the Developer Notes ------------------------------- - -The Developer Notes are divided into sections, each focusing on a different component of the library. Each section provides an overview of the class or module, explains its role and functionality within the library, and offers a comprehensive guide to its classes and functions. -Typically, we will provide instructions on how to extend the existing modules. We generally advocate for the use of inheritance and encourage consistency with the existing codebase. In creating developer instructions, we follow the conventions outlined below: - -- **Must**: This denotes a requirement. Any method or function that fails to meet the requirement will not be merged. -- **Should**: This denotes a suggestion. Reasons should be provided if a suggestion is not followed. -- **May**: This denotes an option that, if implemented, could enhance the user/developer experience but can be overlooked if deemed unnecessary. - -Interact with us ----------------- - -If you're considering contributing to the library, first of all, welcome aboard! As a first step, we recommend that you read the [`CONTRIBUTING.md`](https://github.com/fastplotlib/fastplotlib/blob/main/CONTRIBUTING.md) guidelines. -These will help you understand how to interact with other contributors and how to submit your changes. - -If you have any questions or need further clarification on any of the topics covered in these notes, please don't hesitate to reach out to us. You can do so via the [discussion](https://github.com/fastplotlib/fastplotlib/discussions/landing) forum on GitHub. - -We're looking forward to your contributions and to answering any questions you might have! From 68f1da8af70963fda00faaf22e1c7baf0f88906f Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Tue, 17 Sep 2024 12:25:20 -0400 Subject: [PATCH 6/8] dev notes --- docs/source/developer_notes/graphics.rst | 16 ++-------------- docs/source/developer_notes/index.rst | 12 +----------- docs/source/developer_notes/layouts.rst | 2 +- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/docs/source/developer_notes/graphics.rst b/docs/source/developer_notes/graphics.rst index 508d73751..939f29c53 100644 --- a/docs/source/developer_notes/graphics.rst +++ b/docs/source/developer_notes/graphics.rst @@ -36,7 +36,8 @@ keeps a *private* global dictionary of all ``WorldObject`` instances and users a This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . If you are curious or have more questions on garbage collection in `fastplotlib` you're welcome to post an issue :D. -## add notes on graphic collections +Graphic collections are groups of graphics. For now, we have a ``LineCollection`` which is a group of ``LineGraphic`` objects. We also have a ``LineStack`` which +inherits from ``LineCollection`` and gives some fixed offset between ``LineGraphic`` objects in the collection. Graphic Properties ------------------ @@ -68,16 +69,3 @@ callbacks to indicate that the graphic has been deleted (for example, removing r Other graphics have properties that are relevant to them, for example ``ImageGraphic`` has ``cmap``, ``vmin``, ``vmax``, properties unique to images. - -Contributors Guidelines ------------------------ - -**Implementing New Graphics** - -- **Must** inherit from the superclass ``Graphic`` - -- **May** inherit from intermediate classes such as ``GraphicCollection`` or ``PositionsGraphic`` depending on - the type of graphic you are trying to implement - - - diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst index 34f1eba0e..4e8e52b86 100644 --- a/docs/source/developer_notes/index.rst +++ b/docs/source/developer_notes/index.rst @@ -4,8 +4,7 @@ Developer Notes Welcome to the Developer Notes for `fastplotlib`. These notes aim to provide detailed and technical information about the various modules, classes, and functions that make up this library, as well as guidelines on how to write code that integrates nicely with our package. They are intended to help current and future developers understand -the design decisions, and functioning of the library. Furthermore, these notes aim to provide guidance on how to -modify, extend, and maintain the codebase. +the design decisions, and functioning of the library. Intended Audience ----------------- @@ -22,15 +21,6 @@ These notes are primarily intended for the following groups: Please note that these notes assume a certain level of programming knowledge. Familiarity with Python, object-oriented programming, and the NumPy and pygfx libraries would be beneficial when reading these notes. -Navigating the Developer Notes ------------------------------- - -The Developer Notes are divided into sections, each focusing on a different component of the library. Each section provides an overview of the class or module, explains its role and functionality within the library, and offers a comprehensive guide to its classes and functions. -Typically, we will provide instructions on how to extend the existing modules. We generally advocate for the use of inheritance and encourage consistency with the existing codebase. In creating developer instructions, we follow the conventions outlined below: - -- **Must**: This denotes a requirement. Any method or function that fails to meet the requirement will not be merged. -- **Should**: This denotes a suggestion. Reasons should be provided if a suggestion is not followed. -- **May**: This denotes an option that, if implemented, could enhance the user/developer experience but can be overlooked if deemed unnecessary. Interact with us ---------------- diff --git a/docs/source/developer_notes/layouts.rst b/docs/source/developer_notes/layouts.rst index 973f3b786..3929dd0b9 100644 --- a/docs/source/developer_notes/layouts.rst +++ b/docs/source/developer_notes/layouts.rst @@ -71,4 +71,4 @@ Now that we have understood `PlotArea` and `Subplot` we need a way for the user A `Figure` contains a grid of subplot and has methods such as `show()` to output the figure. `Figure.__init__` basically does a lot of parsing of user arguments to determine how to create -the subplots. All subplots within a `Figure` share the same canvas and use different viewports to create the subplots. \ No newline at end of file +the subplots. All subplots within a `Figure` share the same canvas and use different viewports to create the subplots. From 62f5dd195e7a811d77ecb97334c01432ad886c75 Mon Sep 17 00:00:00 2001 From: Caitlin Lewis Date: Wed, 18 Sep 2024 11:16:40 -0400 Subject: [PATCH 7/8] requested changes --- CONTRIBUTING.md | 54 ++++++++++++++++++++++++++----------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 84422f5c7..ca401a241 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -21,7 +21,7 @@ your classes and functions, and to provide clear, detailed comments within your but also facilitates future maintenance and further development. For more detailed information about `fastplotlib` modules, including design choices and implementation details, visit the -[`For Develeopers`]() section of the package documentation. +[`For Develeopers`](https://fastplotlib.readthedocs.io/en/latest/developer_notes/index.html) section of the package documentation. ## Contributing to the code @@ -33,50 +33,51 @@ In order to contribute, you will need to do the following: 2) Make sure that tests pass 3) Open a Pull Request -The `fastplotlib` package follows the [Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow) workflow. In essence, `main` is the primary branch to which no one is allowed to +The `fastplotlib` package follows the [Git feature branch](https://www.atlassian.com/git/tutorials/comparing-workflows/feature-branch-workflow) workflow. In essence, `main` is the primary branch to which no one is allowed to push directly. All development happens in separate feature branches that are then merged into `main` once we have determined they are ready. When enough changes have accumulated, a new release is generated. This process includes adding a new tag to increment the version number and uploading the new release to PyPI. ### Creating a development environment -You will need a local installation `fastplotlib` which keeps up-to-date with any changes you make. To do so, you will need to fork and clone `fastplotlib` before checking out a new branch. +You will need a local installation of `fastplotlib` which keeps up-to-date with any changes you make. To do so, you will need to fork and clone `fastplotlib` before checking out a new branch. 1. Fork the repo to your own GitHub account, click the "Fork" button at the top: ![image](https://github.com/kushalkolar/fastplotlib/assets/9403332/82612021-37b2-48dd-b7e4-01a919535c17) -2. Clone the repo. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. +2. We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need +to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. If you already have `git-lfs` +installed, ignore this step. -> **_NOTE:_** We use [git-lfs](https://git-lfs.com) for storing large files, such as ground-truths for tests, so you will need -> to [install it](https://github.com/git-lfs/git-lfs#installing) before cloning the repo. +3. Clone the repo. Replace the `YOUR_ACCOUNT` in the repo URL to the fork on your account. ```bash git clone https://github.com/YOUR_ACCOUNT/fastplotlib.git cd fastplotlib ``` -3. Install `fastplotlib` in editable mode with developer dependencies +> **_NOTE:_** If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any +> time to download the files stored on LFS + +4. Install `fastplotlib` in editable mode with developer dependencies ```bash # install all extras in place pip install -e ".[notebook,docs,tests]" ``` -> **_NOTE:_** If you cloned the repo before installing `git-lfs`, you can run `git lfs pull` at any -> time to download the files stored on LFS - -4. Add the upstream remote branch: +5. Add the upstream remote branch: ```bash git remote add upstream https://github.com/fastplotlib/fastplotlib ``` -At this point you have two remotes: `origin` (your fork) and `upstream` (the canonical version). You won't have permission to push to upstream (only `origin`), but -this make it easy to keep your `fastplotlib` up-to-date with the canonical version by pulling from upstream: `git pull upstream`. +At this point you have two remotes: `origin` (your fork) and `upstream` (the official fastplotlib org version). You won't have permission to push to upstream (only `origin`), but +this makes it easy to keep your `fastplotlib` up-to-date with the official fastplotlib org version by pulling from upstream: `git pull upstream`. ### Creating a new branch -As mentioned previously, each feature in `fastplotlib` is worked on in a separate branch. This allows multiple people developing multiple features simultaneously, without interfering with each other's work. To create +As mentioned previously, each feature in `fastplotlib` is worked on in a separate branch. This allows multiple people to develop multiple features simultaneously, without interfering with each other's work. To create your own branch, run the following from within your `fastplotlib` directory: ```bash @@ -122,6 +123,9 @@ git push origin my_feature_branch ``` > **_NOTE:_** If your contributions modify how visualizations _look_, see the [Testing details](#testing-details) section at the very bottom. +> **_NOTE:_** If your contributions modify the API, you must regenerate the API docs before making a PR, see +> the [Documenation](#documentation) section below. + ### Contributing your changes back to `fastplotlib` You can make any number of changes on your branch. Once you are happy with your changes, add tests to check that they run correctly and add @@ -141,12 +145,12 @@ Your pull request should include the following: - Special notice to any portion of your changes where you have lingering questions (e.g., "was this the right way to implement this?") or want reviewers to pay special attention to -Next, we will be notified of the pull request and will read it over. We will try to give and initial response quickly, and then do a longer in-depth +Next, we will be notified of the pull request and will read it over. We will try to give an initial response quickly, and then do a longer in-depth review, at which point you will probably need to respond to our comments, making changes as appropriate. We will then respond again, and proceed in an iterative fashion until everyone is happy with the proposed changes. Once your changes are integrated, you will be added as a GitHub contributor. Thank you for being -apart of `fastplotlib`! +a part of `fastplotlib`! ### Style Guide @@ -154,12 +158,12 @@ As far as code style, please adhere to the following guidelines: - Longer, descriptive names are preferred (e.g., `x` is not an appropriate name for a variable), especially for anything user-facing, such as methods, attributes, or arguments -- Any public method or function must have complete type-annotated docstrings (see below for details). Hidden ones do not need to have -complete docstring, but they probably should. +- Any public method, property, or attribute must have complete type-annotated docstrings (see below for details). Private methods or +attributes do not need to have a complete docstring, but they probably should. ### Releases -We create releases on GitHub, deploy on / distribute via [pypi](https://pypi.org/), and try to follow [semantic versioning](https://semver.org/): +We create releases on GitHub and distribute via [pypi](https://pypi.org/), and try to follow [semantic versioning](https://semver.org/): > Given a version number MAJOR.MINOR.PATCH, increment the: > 1. MAJOR version when you make incompatible API changes @@ -174,8 +178,8 @@ The built version will grab the version tag from the GitHub release, using [setu #### Testing Details -An integral part of our testing suite is not only to test that our code is working, but to also check that are plotting -library CI pipeline is producing things that "look visually correct". +As a plotting library we require two layers of testing. 1) We use a backend test suite that verifies the basic functionality of buffer managers, +graphics, layouts, etc., and 2) another test suite which verifies that the library renders plots that are visually correct. In order to do this, each example within the `examples` directory is run and an image of the canvas is taken and compared with a ground-truth screenshot that we have manually inspected. Ground-truth images are stored using `git-lfs`. @@ -196,7 +200,7 @@ this, please do the following: 1. Download the regenerated screenshots from the [`fastplotlib` GitHub Actions page](https://github.com/fastplotlib/fastplotlib/actions/workflows/screenshots.yml) for your specific PR -2. Replace the screenshots in your local `fastplotlib` screenshots directories with those downloaded +2. Replace only the screenshots that your PR changes in your local `fastplotlib` screenshots directories with those downloaded ``` examples/desktop/screenshots @@ -219,10 +223,10 @@ git push origin my_feature_branch #### Adding tests -Depending on the type of contribution you are making, new tests will need to be added to the repository. Unit tests for testing underlying functionality such as buffer managers, figure instantiation, and +Depending on the type of contribution you are making, new tests might need to be added to the repository. Unit tests for testing underlying functionality such as buffer managers, figure instantiation, and more can be found in the `/tests` directory. However, we also test all of our desktop examples as well. -If you are adding a new example to the library, you will need to add to comments to the top of your `.py` file in order to make sure it is both tested and added to the gallery. +If you are adding a new example to the library, you will need to add the following comments to the top of your `.py` file in order to make sure it is both tested and added to the gallery. ```python # test_example = true @@ -252,7 +256,7 @@ make html All public-facing functions and classes should have complete docstrings, which start with a one-line short summary of the function, a medium-length description of the function / class and what it does, and a complete description of all arguments and return values. -Docstrings should be relatively short, providing the information necessary for a user to use the code. +Docstrings should be comprehensive, providing the information necessary for a user to use the method or property without going through the code. Private functions and classes should have sufficient explanation that other developers know what the function / class does and how to use it, but do not need to be as extensive. From c617635e583a8aa0e308acca6cf8b3c0904e54ac Mon Sep 17 00:00:00 2001 From: Caitlin Date: Fri, 27 Sep 2024 14:53:46 -0400 Subject: [PATCH 8/8] add layouts, fix toctree issue --- docs/source/developer_notes/graphics.rst | 4 +- docs/source/developer_notes/index.rst | 4 +- docs/source/developer_notes/layouts.rst | 91 +++++++++++++----------- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/docs/source/developer_notes/graphics.rst b/docs/source/developer_notes/graphics.rst index 939f29c53..9efe07b79 100644 --- a/docs/source/developer_notes/graphics.rst +++ b/docs/source/developer_notes/graphics.rst @@ -34,7 +34,7 @@ plots, ex: ``subplot["some_image"]``. All graphics contain a ``world_object`` property which is just the ``pygfx.WorldObject`` that this graphic uses. Fastplotlib keeps a *private* global dictionary of all ``WorldObject`` instances and users are only given a weakref proxy to this world object. This is due to garbage collection. This may be quite complicated for beginners, for more details see this PR: https://github.com/fastplotlib/fastplotlib/pull/160 . -If you are curious or have more questions on garbage collection in `fastplotlib` you're welcome to post an issue :D. +If you are curious or have more questions on garbage collection in ``fastplotlib`` you're welcome to post an issue :D. Graphic collections are groups of graphics. For now, we have a ``LineCollection`` which is a group of ``LineGraphic`` objects. We also have a ``LineStack`` which inherits from ``LineCollection`` and gives some fixed offset between ``LineGraphic`` objects in the collection. @@ -58,7 +58,7 @@ In addition, event handlers will be called if any event handlers are registered. ``VertexColors``behaves similarly, but it can perform additional parsing that can create the colors buffer from different forms of user input. For example if a user runs: ``line_graphic.colors = "blue"``, then ``VertexColors.__setitem__()`` will -create a buffer that corresponds to what `pygfx.Color` thinks is "blue". Users can also take advantage of fancy indexing, +create a buffer that corresponds to what ``pygfx.Color`` thinks is "blue". Users can also take advantage of fancy indexing, ex: ``line_graphics.colors[bool_array] = "red"`` :smile: ``LineGraphic`` also has a ``VertexCmap``, this manages the line ``VertexColors`` instance to parse colormaps, for example: diff --git a/docs/source/developer_notes/index.rst b/docs/source/developer_notes/index.rst index 4e8e52b86..1ba4069bd 100644 --- a/docs/source/developer_notes/index.rst +++ b/docs/source/developer_notes/index.rst @@ -35,5 +35,5 @@ We're looking forward to your contributions and to answering any questions you m .. toctree:: :maxdepth: 1 - graphics - layouts \ No newline at end of file + Graphics + Layouts \ No newline at end of file diff --git a/docs/source/developer_notes/layouts.rst b/docs/source/developer_notes/layouts.rst index 3929dd0b9..f478ac5c5 100644 --- a/docs/source/developer_notes/layouts.rst +++ b/docs/source/developer_notes/layouts.rst @@ -1,74 +1,79 @@ -### Layouts +Layouts +======= -#### PlotArea +PlotArea +-------- -This is the main base class within layouts. Subplots within a `Figure` and `Dock` areas within a `Subplot`, -inherit from `PlotArea`. +This is the main base class within layouts. A ``Figure`` and ``Dock`` are areas within a ``Subplot`` that +inherit from ``PlotArea``. -`PlotArea` has the following key properties that allow it to be a "plot area" that can be used to view graphical objects: +``PlotArea`` has the following key properties that allow it to be a "plot area" that can be used to view graphical objects: -* scene - instance of `pygfx.Scene` -* canvas - instance of `WgpuCanvas` -* renderer - instance of `pygfx.WgpuRenderer` -* viewport - instance of `pygfx.Viewport` -* camera - instance of `pygfx.PerspectiveCamera`, we always just use `PerspectiveCamera` and just set `camera.fov = 0` for orthographic projections -* controller - instance of `pygfx.Controller` +* scene - instance of ``pygfx.Scene`` +* canvas - instance of ``WgpuCanvas`` +* renderer - instance of ``pygfx.WgpuRenderer`` +* viewport - instance of ``pygfx.Viewport`` +* camera - instance of ``pygfx.PerspectiveCamera``, we always just use ``PerspectiveCamera`` and just set ``camera.fov = 0`` for orthographic projections +* controller - instance of ``pygfx.Controller`` Abstract method that must be implemented in subclasses: -* get_rect - musut return [x, y, width, height] that defines the viewport rect for this `PlotArea` +* get_rect - must return [x, y, width, height] that defines the viewport rect for this ``PlotArea`` Properties specifically used by subplots in a Figure: -* parent - A parent if relevant, used by individual `Subplots` in `Figure`, and by `Dock` which are "docked" subplots at the edges of a subplot. -* position - if a subplot within a Figure, it is the position of this subplot within the `Figure` +* parent - A parent if relevant, used by individual ``Subplots`` in ``Figure``, and by ``Dock`` which are "docked" subplots at the edges of a subplot. +* position - if a subplot within a ``Figure``, it is the position of this subplot within the ``Figure`` Other important properties: -* graphics - a tuple of weakref proxies to all `Graphics` within this `PlotArea`, users are only given weakref proxies to `Graphic` objects, all `Graphic` objects are stored in a private global dict. -* selectors - a tuple of weakref proxies to all selectors within this `PlotArea` -* legend - a tuple of weakref proxies to all legend graphics within this `PlotArea` +* graphics - a tuple of weakref proxies to all ``Graphics`` within this ``PlotArea``, users are only given weakref proxies to ``Graphic`` objects, all ``Graphic`` objects are stored in a private global dict. +* selectors - a tuple of weakref proxies to all selectors within this ``PlotArea`` +* legend - a tuple of weakref proxies to all legend graphics within this ``PlotArea`` * name - plot areas are allowed to have names that the user can use for their convenience Important methods: -* add_graphic - add a `Graphic` to the `PlotArea`, append to the end of the `PlotArea._graphics` list -* insert_graphic - insert a `Graphic` to the `PlotArea`, insert to a specific position of the `PlotArea._graphics` list -* remove_graphic - remove a graphic from the `Scene`, **does not delete it** -* delete_graphic - delete a graphic from the `PlotArea`, performs garbage collection -* clear - deletes all graphics from the `PlotArea` -* center_graphic - center camera w.r.t. a `Graphic` -* center_scene - center camera w.r.t. entire `Scene` -* auto_scale - Auto-scale the camera w.r.t to the `Scene` +* add_graphic - add a ``Graphic`` to the ``PlotArea``, append to the end of the ``PlotArea._graphics`` list +* insert_graphic - insert a ``Graphic`` to the ``PlotArea``, insert to a specific position of the ``PlotArea._graphics`` list +* remove_graphic - remove a graphic from the ``Scene``, **does not delete it** +* delete_graphic - delete a graphic from the ``PlotArea``, performs garbage collection +* clear - deletes all graphics from the ``PlotArea`` +* center_graphic - center camera w.r.t. a ``Graphic`` +* center_scene - center camera w.r.t. entire ``Scene`` +* auto_scale - Auto-scale the camera w.r.t to the ``Scene`` -In addition, `PlotArea` supports `__getitem__`, so you can do: `plot_area["graphic_name"]` to retrieve a `Graphic` by +In addition, ``PlotArea`` supports ``__getitem__``, so you can do: ``plot_area["graphic_name"]`` to retrieve a ``Graphic`` by name :smile: -You can also check if a `PlotArea` has certain graphics, ex: `"some_image_name" in plot_area`, or `graphic_instance in plot_area` +You can also check if a ``PlotArea`` has certain graphics, ex: ``"some_image_name" in plot_area``, or ``graphic_instance in plot_area`` -#### Subplot +Subplot +------- -This class inherits from `PlotArea` and `GraphicMethodsMixin`. +This class inherits from ``PlotArea`` and ``GraphicMethodsMixin``. -`GraphicMethodsMixin` is a simple class that just has all the `add_` methods. It is autogenerated by a utility script like this: +``GraphicMethodsMixin`` is a simple class that just has all the ``add_`` methods. It is autogenerated by a utility script like this: -```bash -python scripts/generate_add_methods.py -``` +.. code-block:: bash -Each `add_` method basically creates an instance of `Graphic`, adds it to the `Subplot`, and returns a weakref -proxy to the `Graphic`. + python scripts/generate_add_methods.py -Subplot has one property that is not in `PlotArea`: +Each ``add_`` method basically creates an instance of ``Graphic``, adds it to the ``Subplot``, and returns a weakref +proxy to the ``Graphic``. -* docks: a `dict` of `PlotAreas` which are located at the "top", "right", "left", and "bottom" edges of a `Subplot`. By default their size is `0`. They are useful for putting things like histogram LUT tools. +Subplot has one property that is not in ``PlotArea``: -The key method in `Subplot` is an implementation of `get_rect` that returns the viewport rect for this subplot. +* docks: a ``dict`` of ``PlotAreas`` which are located at the "top", "right", "left", and "bottom" edges of a ``Subplot``. +By default their size is ``0``. They are useful for putting things like histogram LUT tools. -#### Figure +The key method in ``Subplot`` is an implementation of ``get_rect`` that returns the viewport rect for this subplot. -Now that we have understood `PlotArea` and `Subplot` we need a way for the user to create them! +Figure +------ -A `Figure` contains a grid of subplot and has methods such as `show()` to output the figure. -`Figure.__init__` basically does a lot of parsing of user arguments to determine how to create -the subplots. All subplots within a `Figure` share the same canvas and use different viewports to create the subplots. +Now that we have understood ``PlotArea`` and ``Subplot`` we need a way for the user to create them! + +A ``Figure`` contains a grid of subplot and has methods such as ``show()`` to output the figure. +``Figure.__init__`` basically does a lot of parsing of user arguments to determine how to create +the subplots. All subplots within a ``Figure`` share the same canvas and use different viewports to create the subplots.