Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions docs/backends.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,6 @@ The table below gives an overview of the names in the different ``rendercanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (an ``AsyncioLoop``)
- | A lightweight backend.
* - ``jupyter``
- | ``JupyterRenderCanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (an ``AsyncioLoop``)
- | Integrate in Jupyter notebook / lab.
* - ``offscreen``
- | ``OffscreenRenderCanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (a ``StubLoop``)
- | For offscreen rendering.
* - ``qt``
- | ``QRenderCanvas`` (toplevel)
| ``RenderCanvas`` (alias)
Expand All @@ -46,14 +36,28 @@ The table below gives an overview of the names in the different ``rendercanvas``
| ``loop``
- | Create a standalone canvas using wx, or
| integrate a render canvas in a wx application.
* - ``offscreen``
- | ``OffscreenRenderCanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (a ``StubLoop``)
- | For offscreen rendering.
* - ``anywidget``
- | ``AnywidgetRenderCanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (an ``AsyncioLoop``)
- | Integrate in notebooks using anywidget.
* - ``jupyter``
- | ``JupyterRenderCanvas``
| ``RenderCanvas`` (alias)
| ``loop`` (an ``AsyncioLoop``)
- | Integrate in notebooks via ``jupyter_rfb`` (deprecated).
* - ``pyodide``
- | ``PyodideRenderCanvas`` (toplevel)
| ``RenderCanvas`` (alias)
| ``loop`` (an ``AsyncioLoop``)
- | Backend when Python is running in the browser,
| via Pyodide or PyScript.


There are also three loop-backends. These are mainly intended for use with the glfw backend:

.. list-table::
Expand Down Expand Up @@ -262,17 +266,17 @@ object, but in some cases it's convenient to do so with a canvas-like API.
array = canvas.draw() # numpy array with shape (400, 500, 4)


Support for Jupyter lab and notebook
------------------------------------
Support for notebooks
---------------------

With the ``anywidget`` backend, RenderCanvas can be used in Jupyter lab, Jupyter notebook, VSCode, Google Colab, Marimo notebooks, and anywhere else where ``anywidget`` is supported.
When the ``auto`` backend is used in a notebook, the ``anywidget`` is selected automatically.

RenderCanvas can be used in Jupyter lab and the Jupyter notebook. This canvas
is based on `jupyter_rfb <https://github.com/vispy/jupyter_rfb>`_, an ipywidget
subclass implementing a remote frame-buffer. There are also some `wgpu examples <https://jupyter-rfb.readthedocs.io/en/stable/examples/>`_.
The ``jupyter`` backend is the previous backend to provide notebook support, which is based on ``jupyter_rfb``. It's kept for backwards compatibility.

.. code-block:: py

# from rendercanvas.jupyter import RenderCanvas # Direct approach
from rendercanvas.auto import RenderCanvas # also works, because rendercanvas detects Jupyter
from rendercanvas.auto import RenderCanvas # uses anywidget when in a notebook

canvas = RenderCanvas()

Expand All @@ -281,6 +285,10 @@ subclass implementing a remote frame-buffer. There are also some `wgpu examples
canvas # Use as cell output


.. autoclass:: rendercanvas.anywidget.AnywidgetRenderCanvas
:members:


Support for Pyodide
-------------------

Expand Down Expand Up @@ -417,9 +425,8 @@ Many interactive environments have some sort of GUI support, allowing the repl
to stay active (i.e. you can run new code), while the GUI windows is also alive.
In rendercanvas we try to select the GUI that matches the current environment.

On ``jupyter notebook`` and ``jupyter lab`` the jupyter backend (i.e.
``jupyter_rfb``) is normally selected. When you are using ``%gui qt``, rendercanvas will
honor that and use Qt instead.
In a notebook (e.g. jupyter) one of the notebook capable backends (``anywidget`` or ``jupyter``) is selected.
When you are using ``%gui qt``, rendercanvas will honor that and use Qt instead.

On ``jupyter console`` and ``qtconsole``, the kernel is the same as in ``jupyter notebook``,
making it (about) impossible to tell that we cannot actually use
Expand Down
26 changes: 26 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,32 @@
os.environ["RENDERCANVAS_FORCE_OFFSCREEN"] = "true"


class FakeTrait:
def __init__(self, *args, **kwargs):
pass

def tag(self, *args, **kwargs):
pass


class FakeModule:
# from anywidget import AnyWidget
AnyWidget = object
# from traitlets import ...
Dict = FakeTrait
Unicode = FakeTrait
Int = FakeTrait
Bool = FakeTrait
# from IPython.display import ...
HTML = lambda *a, **kw: None
display = lambda *a, **kw: None


sys.modules["anywidget"] = FakeModule
sys.modules["traitlets"] = FakeModule
sys.modules["IPython.display"] = FakeModule


# Load wgpu so autodoc can query docstrings
import rendercanvas # noqa: E402
import rendercanvas.stub # noqa: E402 - we use the stub backend to generate docs
Expand Down
36 changes: 26 additions & 10 deletions examples/rendercanvas.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@
"metadata": {},
"outputs": [],
"source": [
"# from rendercanvas.anywidget import RenderCanvas\n",
"# from rendercanvas.jupyter import RenderCanvas\n",
"from rendercanvas.auto import RenderCanvas # Defaults to anywidget when in a notebook\n",
"from rendercanvas.utils.cube import setup_drawing_sync\n",
"from rendercanvas.jupyter import RenderCanvas\n",
"\n",
"canvas = RenderCanvas(update_mode=\"continuous\")\n",
"draw_frame = setup_drawing_sync(canvas)\n",
Expand All @@ -41,7 +43,29 @@
"outputs": [],
"source": [
"# Set title to non-empty string to show the title bar\n",
"canvas.set_title(\"Rotating cube\")"
"canvas.set_title(\"Rotating cube\")\n",
"canvas.set_minimizable(True)\n",
"canvas.set_closable(True)"
]
},
{
"cell_type": "markdown",
"id": "da1ea8e0-e7bd-41a1-b2f5-0084d0d48888",
"metadata": {},
"source": [
"## Snapshots\n",
"\n",
"It is also possible to create snapshots. This is also possible without displaying the interactive canvas itself. The benefit of snapshots is that the output remains visible when the notebook is shown in a static viewer. This makes them useful for e.g. tutorials."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "16a4a4fe-4c64-4c07-8da9-577a1a010fbe",
"metadata": {},
"outputs": [],
"source": [
"canvas.snapshot()"
]
},
{
Expand Down Expand Up @@ -72,14 +96,6 @@
"\n",
"out"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "65f86895-9e9a-4c22-8a54-919bd70fd80b",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
19 changes: 10 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,24 @@ keywords = [
"jupyter",
]
requires-python = ">= 3.10"
dependencies = ['numpy'] # Numpy is the only hard dependency
dependencies = ["numpy"] # Numpy is the only hard dependency

[project.optional-dependencies]
# For users
jupyter = ["jupyter_rfb>=0.4.2"]
jupyter = ["jupyter_rfb>=0.4.2", "simplejpeg; implementation_name != 'pypy'"]
notebook = ["anywidget", "simplejpeg; implementation_name != 'pypy'"]
glfw = ["glfw>=1.9"]
# For devs / ci
lint = ["ruff", "pre-commit"]
examples = ["flit", "numpy", "wgpu", "glfw", "pyside6", "imageio", "pytest"]
docs = [
"flit",
"sphinx>7.2",
"sphinx_rtd_theme",
"sphinx-gallery",
"numpy",
docs = ["flit", "sphinx>7.2", "sphinx_rtd_theme", "sphinx-gallery", "wgpu"]
tests = [
"pytest",
"wgpu",
"glfw",
"trio",
"simplejpeg; implementation_name != 'pypy'",
]
tests = ["pytest", "numpy", "wgpu", "glfw", "trio"]
dev = ["rendercanvas[lint,tests,examples,docs]"]

[project.entry-points."pyinstaller40"]
Expand Down
Loading
Loading