Here we recommend the input arguments, return value, and behavior of the
plot method of a class.
- Convenience to interactive users. This is the highest priority.
Compared to being called in a batch script as a library (for composing
more complicated plots or other purposes), the
plotmethod is mainly used in interactive sessions like ipython, jupyter, colab, PyCharm, and python interpreter.
- Plot is customizable. The plot should be customizable by the user after
plotreturns. This is important because user may need to change the look for presentation, paper, or just the style they prefer. One plot style does not fit all.
- No unnecessary messages in interactive sessions. It should not produce any warning/error messages in normal usages in an interactive sessions. See #1890 for an example of such message.
- No popups during tests. It should not produce any pop-up windows during tests.
plot method must produce a plot when there is no arguments in an
interactive session. The recommended way to achieve that is illustrated in the
from typing import Any, List, Optional import matplotlib.pyplot as plt class Foo: ... def plot(self, ax: Optional[plt.Axes]=None, **plot_kwargs: Any) -> plt.Axes: show_plot = not ax if not ax: fig, ax = plt.subplots(1, 1) # or your favorite figure setup # Call methods of the ax instance like ax.plot to plot on it. ... if show_plot: fig.show() return ax
plot method works in 2 modes: memory mode and interactive mode,
signalled by the presence of the
ax argument. When present, the method is
instructed to plot on the provided
ax instance in memory. No plot is shown
on the screen. When absent, the code is in interactive mode, and it creates
a figure and shows it.
ax instance can be used to further customize the plot if the
user wants to. Note that if we were to call
plt.show instead of
the customizations on the returned
ax does not show up on subsequent call to
To satisfy requirement number 4, unit test codes should create an
and pass it into the
plot method like the following example.
def test_foo_plot(): # make a Foo instance foo figure, ax = plt.subplots(1, 1) foo.plot(ax) # assert on the content of ax here if necessary.
This does not produce a pop-up window because
fig.show is not called.
Classes that produce multi-axes plot
Some classes contain complicated data and plotting on a single
not sufficient. The
plot method of such a class should take an optional
axes argument that is a list of
class Foo: ... def plot(self, axes: Optional[List[plt.Axes]]=None, **plot_kwargs: Any) -> List[plt.Axes]: show_plot = not axes if not axes: fig, axes = plt.subplots(1, 2) # or your favorite figure setup elif len(axes) != 2: # your required number of axes raise ValueError('your error message') # Call methods of the axes[i] objects to plot on it. ... if show_plot: fig.show() return axes
The reason we don't recommend passing a
plt.Figure argument is that, the
plot method has no information on which
plt.Axes objects to plot on if
there are more
plt.Axes in the figure than what the method needs. The caller
is responsible for passing in correct number of
plot method can be tested similarly.
As of this writing in October 2019, running a script calling a
in PyCharm does not pop up a window with the figure. A call to
is needed to show it. We believe this is a PyCharm-specific issue because
the same code works in Python interpreter.
- Issue #1890 "Plotting code should not call
- PR #2097
- PR #2286