This project is a prototype space for overhauling the GUI event loop management tools that Matplotlib provides in pyplot.
The pyplot module current serves two critical, but unrelated functions:
provide a state-full implicit API that rhymes / was inspired by MATLAB
provide the management of interaction between Matplotlib and the GUI event loop, including keeping Figures alive
While it can be very convenient when working at the prompt, the state-full API can lead to brittle code that depends on the global state in confusing ways, particularly when used in library code. On the other hand, matplotlib.pyplot
does a very good job of hiding from the user the fact that they are developing a GUI application and handling, along with IPython, many of the details involved in running a GUI application in parallel with Python.
If you want to be sure that this code does not secretly depend on pyplot run
import sys sys.modules['matplotlib.pyplot'] = None
which will prevent pyplot from being imported!
showing#The core of the API is show
import mpl_gui as mg from matplotlib.figure import Figure fig1 = Figure(label='A Label!') fig2 = Figure() mg.show([fig1, fig2])
which will show both figures and block until they are closed. As part of the “showing” process, the correct GUI objects will be created, put on the screen, and the event loop for the host GUI framework is run.
blocking (or not)#Similar to plt.ion
and plt.ioff
, we provide mg.ion()
and mg.ioff()
which have identical semantics. Thus
import mpl_gui as mg from matplotlib.figure import Figure mg.ion() print(mg.is_interactive()) fig = Figure() mg.show([fig]) # will not block mg.ioff() print(mg.is_interactive()) mg.show([fig]) # will block!
As with plt.show
, you can explicitly control the blocking behavior of mg.show
via the block keyword argument
import mpl_gui as mg from matplotlib.figure import Figure fig = Figure(label='control blocking') mg.show([fig], block=False) # will never block mg.show([fig], block=True) # will always block
The interactive state is shared Matplotlib and can also be controlled with matplotlib.interactive
and queried via matplotlib.is_interactive
.
In analogy with matplotlib.pyplot
we also provide figure
, subplots
and subplot_mosaic
import mpl_gui as mg fig1 = mg.figure() fig2, axs = mg.subplots(2, 2) fig3, axd = mg.subplot_mosaic('AA\nBC') mg.show([fig1, fig2, fig3])
If mpl_gui
is in “interactive mode”, mpl_gui.figure
, mpl_gui.subplots
and mpl_gui.subplot_mosaic
will automatically put the new Figure in a window on the screen (but not run the event loop).
In the above examples it is the responsibility of the user to keep track of the Figure
instances that are created. If the user does not keep a hard reference to the fig
object, either directly or indirectly through its children, then it will be garbage collected like any other Python object. While this can be advantageous in some cases (such as scripts or functions that create many transient figures). It loses the convenience of matplotlib.pyplot
keeping track of the instances for you. To this end we also have provided FigureRegistry
import mpl_gui as mg fr = mg.FigureRegistry() fr.figure() fr.subplots(2, 2) fr.subplot_mosaic('AA\nBC') fr.show_all() # will show all three figures fr.show() # alias for pyplot compatibility fr.close_all() # will close all three figures fr.close('all') # alias for pyplot compatibility
Thus, if you are only using this restricted set of the pyplot API then you can change
import matplotlib.pyplot as plt
to
import mpl_gui as mg plt = mg.FigureRegistry()
and have a (mostly) drop-in replacement.
Additionally, there is a FigureRegistry.by_label
accessory that returns a dictionary mapping the Figures’ labels to each Figure
import mpl_gui as mg fr = mg.FigureRegistry() figA = fr.figure(label='A') figB = fr.subplots(2, 2, label='B') fr.by_label['A'] is figA fr.by_label['B'] is figBFigureContext#
A very common use case is to make several figures and then show them all together at the end. To facilitate this we provide a sub-class of FigureRegistry
that can be used as a context manager that (locally) keeps track of the created figures and shows them on exit
import mpl_gui as mg with mg.FigureContext() as fc: fc.subplot_mosaic('AA\nBC') fc.figure() fc.subplots(2, 2)
This will create 3 figures and block on __exit__
. The blocking behavior depends on mg.is_interacitve()
(and follow the behavior of mg.show
or can explicitly controlled via the block keyword argument).
mpl_gui
makes use of Matplotlib backends for actually providing the GUI bindings. Analagous to matplotlib.use
and matplotlib.pyplot.switch_backend
mpl_gui
provides mpl_gui.select_gui_toolkit
to select which GUI toolkit is used. select_gui_toolkit
has the same fall-back behavior as pyplot
and stores its state in rcParams["backend"]
. mpl_gui
will consistently co-exist with matplotlib.pyplot
managed Figures in the same process.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4