-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #44 from GLVis/anywidget
Rewrite to use anywidget
- Loading branch information
Showing
29 changed files
with
310 additions
and
3,764 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,2 @@ | ||
# install this | ||
pip install . | ||
|
||
# install jupyter-lab extension | ||
jupyter labextension install @jupyter-widgets/jupyterlab-manager --no-build | ||
jupyter labextension install glvis-jupyter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,197 +1,152 @@ | ||
# Interactive GLVis Jupyter Widget | ||
# PyGLVis | ||
|
||
<!-- Badges generated at https://mybinder.readthedocs.io/en/latest/howto/badges.html --> | ||
[![badge](examples/basic.svg "Basic GLVis + Jupyter Example")](https://mybinder.org/v2/gh/GLVis/pyglvis/HEAD?filepath=examples%2Fbasic.ipynb) | ||
[![badge](examples/plot.svg "Plot grid functions")](https://mybinder.org/v2/gh/GLVis/pyglvis/HEAD?filepath=examples%2Fplot.ipynb) | ||
[![badge](examples/ex1.svg "MFEM's Example 1")](https://mybinder.org/v2/gh/GLVis/pyglvis/HEAD?filepath=examples%2Fex1.ipynb) | ||
[![badge](examples/ex9.svg "MFEM's Example 9")](https://mybinder.org/v2/gh/GLVis/pyglvis/HEAD?filepath=examples%2Fex9.ipynb) | ||
|
||
This repository contains a [Jupyter](https://jupyter.org/) widget for the [GLVis](https://glvis.org/) finite element | ||
visualization tool based on the [glvis-js](https://github.com/GLVis/glvis-js) JavaScript/WebAssembly library. | ||
PyGLVis is an interactive [Jupyter](https://jupyter.org/) widget for visualizing finite element meshes and functions, built on-top of the [GLVis](https://glvis.org/) library. | ||
|
||
## Usage | ||
## 📦 Installation | ||
|
||
```python | ||
from glvis import glvis | ||
The GLVis Jupyter widget is installed using `pip`. To install the latest version from the repository: | ||
|
||
glvis(data[, width=640, height=480]) | ||
```bash | ||
git clone https://github.com/GLVis/pyglvis.git | ||
cd pyglvis | ||
pip install . | ||
``` | ||
|
||
# or assign if you want to update later | ||
g = glvis(data) | ||
# run a cell with `g` to show it | ||
g | ||
Or, install directly from PyPi, | ||
```bash | ||
pip install glvis | ||
``` | ||
|
||
The `data` object and be one of: | ||
PyGLVis requires the Python wrapper for MFEM, [PyMFEM](https://github.com/mfem/pymfem), which can be installed with | ||
```bash | ||
pip install mfem | ||
``` | ||
|
||
- a `str`, in the format of `*.saved` files | ||
- a `Mesh`, defined in [PyMFEM](https://github.com/mfem/pymfem) | ||
- a `(Mesh, GridFunction)` tuple, defined in [PyMFEM](https://github.com/mfem/pymfem) | ||
|
||
[PyMFEM](https://github.com/mfem/pymfem) can be installed with `pip install mfem --no-binary mfem`. | ||
|
||
## 🚀 Usage | ||
|
||
### Basic usage | ||
|
||
Once you have a `glvis` object there are a few methods that can used to update the | ||
visualization: | ||
```python | ||
# show a new Mesh/GridFunction, resets keys | ||
g.plot(data) | ||
# show an updated visualization with the same `Mesh` and `GridFunction` | ||
# dimensions, preserves keys | ||
g.update(data) | ||
# change the image size | ||
g.set_size(width, height) | ||
# force the widget to render. if the widget isn't the last statement in a cell it | ||
# will not be shown without this. see ex9.ipynb | ||
g.render() | ||
``` | ||
from glvis import glvis | ||
|
||
See the [examples](examples/) directory for additional examples. To test those locally, start a Jupyter notebook server with | ||
# Create a `glvis` object | ||
g = glvis(data, width=640, height=480) | ||
|
||
# Run a cell with `g` as the last statement to display the widget | ||
g | ||
``` | ||
jupyter notebook | ||
``` | ||
|
||
## Installation | ||
|
||
The GLVis Jupyter widget can be simply installed with `pip`: | ||
|
||
``` | ||
pip install glvis | ||
``` | ||
The `data` object can be one of: | ||
|
||
It order for the installation to be useful you must enable the extension for one or both | ||
of the [Classic Notebook](https://jupyter-notebook.readthedocs.io/en/stable/) and | ||
[Jupyter Lab](https://jupyterlab.readthedocs.io/en/stable/), see the next two sections: | ||
- `Mesh`, defined in [PyMFEM](https://github.com/mfem/pymfem) | ||
- `(Mesh, GridFunction)` tuple, defined in [PyMFEM](https://github.com/mfem/pymfem) | ||
- `str`, in the format of `*.saved` files [used by MFEM and GLVis](https://mfem.org/mesh-format-v1.0/). See [examples/basic.ipynb](examples/basic.ipynb) for an example. | ||
|
||
### Jupyter Notebook | ||
### Customization with key commands | ||
|
||
To use the widget with the basic Notebook enable it with `jupyter nbextension enable`: | ||
GLVis has many keyboard commands that can be used to customize the visualization. | ||
A few of the most common are listed below. See the [GLVis README](https://github.com/GLVis/glvis?tab=readme-ov-file#key-commands) for a full list. | ||
- `r` - reset the view | ||
- `c` - toggle the colorbar | ||
- `j` - toggle perspective | ||
- `l` - toggle the light | ||
- `g` - toggle the background color (white/black) | ||
- `a` - cycle through bounding box axes states | ||
- `m` - cycle through mesh states | ||
- `p` - cycle through color palettes | ||
- `t` - cycle through materials and lights | ||
- `0` - begin rotating around z-axis | ||
- `.` - pause rotation | ||
- `*`/`/` - zoom in/out | ||
|
||
These can be set using the `keys` argument when creating a `glvis` object. | ||
```python | ||
glvis(data, keys='rljgac//0') | ||
``` | ||
jupyter nbextension enable --py glvis | ||
``` | ||
|
||
After enabling the extension you can verify you're good to go with: | ||
This combination of keys would: `r` reset the view, `l` toggle the light, `j` toggle perspective, `g` toggle the background color to black (default is white), `a` show the bounding box, `c` show the colorbar, `//` zoom out twice, and `0` begin rotating around the z-axis: | ||
|
||
``` | ||
jupyter nbextension list | ||
``` | ||
![pyglvis_preset_keys](https://github.com/GLVis/pyglvis/assets/27717785/de0e0a99-72ac-4a88-8369-708515600b09) | ||
|
||
The output should be something like: | ||
Alternatively, keys can be typed directly into the widget after it has been created: | ||
|
||
``` | ||
Known nbextensions: | ||
config dir: path/to/nbconfig | ||
notebook section | ||
glvis-jupyter/extension enabled | ||
- Validating: OK | ||
<possibly a different config dir> | ||
jupyter-js-widgets/extension enabled | ||
- Validating: OK | ||
``` | ||
![pyglvis_using_keys](https://github.com/GLVis/pyglvis/assets/27717785/625f4f06-8f99-4390-94d7-4d317fd11e7f) | ||
|
||
If `glvis-jupyter` and `jupyter-js-widgets` are not both listed, try the following: | ||
### Other methods | ||
|
||
Once you have a `glvis` object there are a few methods that can used to update the | ||
visualization, besides using keys: | ||
```python | ||
# Show a new Mesh/GridFunction, resets keys | ||
g.plot(data) | ||
# Show an updated visualization with the same data, preserving keys | ||
g.update(data) | ||
# Change the image size | ||
g.set_size(width, height) | ||
# Force the widget to render. If the widget isn't the last statement in a cell it | ||
# will not be shown without this. See ex9.ipynb | ||
g.render() | ||
``` | ||
jupyter nbextension install --user --py glvis | ||
jupyter nbextension enable --user --py glvis | ||
jupyter nbextension install --user --py widgetsnbextension | ||
jupyter nbextension enable --user --py widgetsnbextension | ||
``` | ||
You may also need to run these if you have upgraded to a newer version of the GLVis Jupyter widget. | ||
|
||
### Jupyter Lab | ||
|
||
[JupyterLab](https://jupyterlab.readthedocs.io) requires another set of install commands: | ||
See the [examples](examples/) directory for additional examples. To test those locally, start a Jupyter lab server with | ||
|
||
``` | ||
jupyter labextension install @jupyter-widgets/jupyterlab-manager --no-build | ||
jupyter labextension install glvis-jupyter | ||
jupyter lab | ||
``` | ||
|
||
## Development | ||
|
||
Development installation requires `npm`. | ||
## 🐛 Troubleshooting | ||
|
||
If you want to test a new version of `glvis`: | ||
This widget was originally developed using the [jupyter widget cookiecutter](https://github.com/jupyter-widgets/widget-cookiecutter); however, [recent changes to the Jupyter ecosystem](https://jupyter-notebook.readthedocs.io/en/latest/migrate_to_notebook7.html#why-a-new-version) have broken a lot of functionality, leading to a rewrite using [anywidget](https://anywidget.dev/). If you encounter any problems, please consider supporting development by opening an [issue](https://github.com/GLVis/pyglvis/issues). | ||
|
||
1. Bump the version in _pyglvis/js/package.json_ and _glvis-js/package.json_ | ||
2. `npm install path/to/glvis-js` | ||
|
||
|
||
Each time you update stuff in _pyglvis/js/src_: | ||
## 🤖 Development | ||
|
||
1. `npm install` | ||
2. `npx webpack` | ||
|
||
|
||
Once: | ||
### PyGLVis dependencies | ||
|
||
```mermaid | ||
graph TD; | ||
A[mfem] --> B[pymfem]; | ||
A --> C[glvis]; | ||
C --> D[glvis-js]; | ||
Ext1[emscripten] --> D; | ||
D-.-E["glvis-js\n(npm/esm mirror)"] | ||
B & E --> G[pyglvis]; | ||
Ext2[jupyter] --> G; | ||
``` | ||
git clone https://github.com/glvis/pyglvis.git | ||
cd pyglvis | ||
pip install -e . | ||
``` | ||
|
||
### Developing in Jupyter Notebook | ||
`pyglvis` is most directly depednent on `PyMFEM` and `glvis-js`. [PyMFEM](https://github.com/mfem/pymfem) is a Python wrapper of the finite element library, `MFEM`, while `glvis-js` is a JavaScript/WebAssembly port of `glvis`. | ||
|
||
`glvis-js` is hosted on [github](https://github.com/glvis/glvis-js) and mirrored on [npm](https://www.npmjs.com/package/glvis). [esm.sh](https://esm.sh/glvis) allows `pyglvis` to pull the latest version of `glvis-js` directly from npm. This can be seen in the first line of [glvis/widget.js](glvis/widget.js): | ||
|
||
``` | ||
jupyter nbextension install --py --symlink --sys-prefix glvis | ||
jupyter nbextension enable --py --sys-prefix glvis | ||
import glvis from "https://esm.sh/glvis"; | ||
``` | ||
|
||
### Developing in Jupyter Lab | ||
You can specify a different version of `glvis-js` by adding `@x.y.z` to the end of this import statement, where `x.y.z` matches a version number available on `npm`, e.g. | ||
|
||
```bash | ||
jupyter labextension install @jupyter-widgets/jupyterlab-manager --no-build | ||
# I believe you need node in the path Lab uses for this to work, I see an extension load error | ||
# in a context where I don't have it: | ||
# Failed to load resource: the server responded with a status of 500 (Internal Server Error) | ||
# lab/api/extensions?1610138347763 | ||
# Which is just a python stacktrace, ending with: | ||
# raise ValueError(msg) | ||
# ValueError: Please install Node.js and npm before continuing installation. | ||
jupyter labextension link ./js | ||
``` | ||
|
||
|
||
### Troubleshooting | ||
|
||
If you run into errors related to node/npm that aren't helpful try: | ||
|
||
```bash | ||
cd pyglvis | ||
make clean | ||
cd js | ||
# fix errors in these steps, run `make -C .. clean` each time | ||
npm install | ||
npx webpack | ||
import glvis from "https://esm.sh/[email protected]"; | ||
``` | ||
|
||
## Releasing | ||
|
||
### Releasing a new version of glvis-jupyter on NPM: | ||
### Releasing a new version of glvis on NPM: | ||
|
||
- Update the required version of `glvis` in `js/package.json` | ||
To publish a new version of `glvis-js`, follow the instructions on the [repo](https://github.com/GLVis/glvis-js/tree/master). | ||
|
||
- Update the version in `js/package.json` | ||
|
||
```bash | ||
# clean out the `dist` and `node_modules` directories | ||
git clean -fdx | ||
npm install | ||
npm publish | ||
``` | ||
|
||
### Releasing a new version of glvis on PyPI: | ||
|
||
- Update `glvis/_version.py` | ||
- Set release version | ||
- Update `extension_version` to match `js/package.json` | ||
- Update `__version__` in `glvis/__about__.py` | ||
|
||
- `git add` and `git commit` changes | ||
- `glvis/_version.py`, `js/package.json`, and `js/package-lock.js` | ||
|
||
|
||
You will need [twine](https://pypi.org/project/twine/) to publish to PyPI, install with `pip`. | ||
|
@@ -202,3 +157,11 @@ twine upload dist/* | |
git tag -a X.X.X -m 'comment' | ||
git push --tags | ||
``` | ||
|
||
|
||
## 🌐 Links | ||
- MFEM ([website](https://mfem.org/), [github](https://github.com/mfem/mfem)) | ||
- PyMFEM ([github](https://github.com/mfem/pymfem), [pypi](https://pypi.org/project/mfem/)) | ||
- GLVis ([website](https://glvis.org/), [github](https://github.com/glvis/glvis)) | ||
- glvis-js ([github](https://github.com/glvis/glvis-js), [npm](https://www.npmjs.com/package/glvis), [esm](https://esm.sh/glvis)) | ||
- pyglvis ([github](https://github.com/GLVis/pyglvis), [pypi]()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.