From 0af2455189fa8726794ea259a7ef3ee90bde1684 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Fri, 18 Apr 2025 16:18:50 -0700 Subject: [PATCH 1/2] DOC: add the API notes from Matplotlib discussion --- docs/source/Api_Notes.md | 83 ++++++++++++++++++++++++++++++++++++++++ docs/source/conf.py | 1 + docs/source/index.rst | 1 + requirements-doc.txt | 1 + 4 files changed, 86 insertions(+) create mode 100644 docs/source/Api_Notes.md diff --git a/docs/source/Api_Notes.md b/docs/source/Api_Notes.md new file mode 100644 index 0000000..bcf59e2 --- /dev/null +++ b/docs/source/Api_Notes.md @@ -0,0 +1,83 @@ +# API design notes + +## Current state + +### `fig, ax = plt.subplots() # and friends` + +- To show during interactive use or in a script: `plt.show()` will show all figures that have been created by pyplot that have note been `plt.close()`d. +- `plt.show(block=False)` will show the current figure, but continue the script. +- works with `inline` +- works with ipympl + +#### Pros: + +- easy to show all plots. + +#### Cons: + +- mixed in with rest of `pyplot` +- too many figures open; must manually close the ones we don't want anymore or memory grows. For a large jupyter notebook with cells executed many times, this can actually be substantial. + +### `fig = matplotlib.figure.Figure()` + +- cannot do `fig.show()`, but can do `fig.savefig()` +- does not display anything in either `inline` or `ipympl` + +### Pros: + +- `fig` will be garbage collected because there are no references stored in a registry + +### Cons: + +- no way to show the figure on a GUI backend (no promotion possible). +- ugly import. + +## Proposed changes + +### `mpl_gui` + +- `import matplotlib.mpl_gui as mg; fig, ax = mg.subplots()` +- Can be shown, but with new `mg.show([fig])` (though singleton fig could trivially be added). +- jupyter: works without `show` in `ipympl`; does _not_ (currently) work (at all) with `inline`. + +#### Pros: + +- no global state - garbage collection on dereferenced figures +- no connection to pyplot state-based interface + +#### Cons: + +- New import and documentation (inertia relative to pyplot) +- `mg.show()` doesn't know what figures to show, so it must be supplied a list of figures. + - sometimes we create figures in loops, and assigning a different variable name to each figure to stop if from being dereferenced could be cumbersome. + +### `mpl_gui.registry` + +- `import matplotlib.mpl_gui.registry as mr; fig, ax = mr.subplots()` +- allows `mr.show()` to be exactly the same as `plt.show`. + +#### Pros: + +- no connection to pyplot state-based interface +- exactly same as previous pyplot interface for this type of work. + +#### Cons: + +- figures must be explicitly closed + +### `mpl_gui.FigureContext` + +This is between the two extremes, where there is no global registry, but a registry is maintained for a series of plots within a context: + +``` +with mg.FigureContext() as fc: + fig, ax = fc.subplots() + fig, ax = fc.subplot_mosaic('AA\nBC') + fig = fc.figure +``` + +makes three figures and shows them in a blocking manner, and then removes the registry on completion. + +### Top-level import? + +The question arose as to whether these should be top level imports eg `fig, ax = mpl.subplots()` A choice would need to be made as to whether that is the registry or non-registry version of the new interface. diff --git a/docs/source/conf.py b/docs/source/conf.py index 8453e3f..bdd822a 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -51,6 +51,7 @@ "matplotlib.sphinxext.plot_directive", "numpydoc", "sphinx_copybutton", + "myst_parser", ] # Configuration options for plot_directive. See: diff --git a/docs/source/index.rst b/docs/source/index.rst index 72bbf95..084233c 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -14,6 +14,7 @@ api release_history min_versions + Api_Notes Motivation diff --git a/requirements-doc.txt b/requirements-doc.txt index a234e53..20aa17f 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -6,3 +6,4 @@ mpl-sphinx-theme~=3.9.0 numpydoc sphinx sphinx-copybutton +myst-parser From d8942651336969e7c92f58bfd5fda8f34214ca82 Mon Sep 17 00:00:00 2001 From: Jody Klymak Date: Fri, 18 Apr 2025 16:21:32 -0700 Subject: [PATCH 2/2] Update docs/source/Api_Notes.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- docs/source/Api_Notes.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/source/Api_Notes.md b/docs/source/Api_Notes.md index bcf59e2..20fe780 100644 --- a/docs/source/Api_Notes.md +++ b/docs/source/Api_Notes.md @@ -49,8 +49,7 @@ - New import and documentation (inertia relative to pyplot) - `mg.show()` doesn't know what figures to show, so it must be supplied a list of figures. - - sometimes we create figures in loops, and assigning a different variable name to each figure to stop if from being dereferenced could be cumbersome. - + - sometimes we create figures in loops, and assigning a different variable name to each figure to stop it from being dereferenced could be cumbersome. ### `mpl_gui.registry` - `import matplotlib.mpl_gui.registry as mr; fig, ax = mr.subplots()`