I have a question that is related to both Matplotlib and Jupyter notebooks, so I’m not even sure this is the right place to ask (so if not just let me know).
Let’s say that I have a custom plot function which generates a complicated plot in a
Figure (so in general it consists of multiple
Axes). Now according to the documentation, the preferred function signature includes an
Axis argument, and the function returns some collection of objects that have changed:
def my_plotter(ax, data1, data2, param_dict): """ A helper function to make a graph. """ out = ax.plot(data1, data2, **param_dict) return out
However, I am not sure how to implement this pattern when my figure consists of several
Axes. Currently, my function returns the whole
Figure, because this makes it easy for users to modify it later. Therefore, a minimal example for my function looks like this:
import matplotlib.pyplot as plt def plot_fig(): fig, ax = plt.subplots() ax.plot(1) return fig
This works fine in most cases, but there is a problem when using this function in a Jupyter notebook – it produces two plots instead of one:
It doesn’t matter if the backend is the default static one or the widget one, there are always two plots:
It seems like one output is generated by the function, and the other by the object’s
repr(), or rather
_repr_html_() method. I could “fix” this simple example as follows (and yes, this kind of monkey-patching is pretty ugly):
def plot_fig_repr(): fig, ax = plt.subplots() ax.plot(1) fig._repr_html_ = lambda self=fig: "" return fig
Another “fix” would be to tell users to assign a name to the function call, but I don’t want this special-casing either:
_ = plot_fig()
Is this the way to go (i.e. expected behavior)? Or are there better alternatives and/or best practices on how to write such custom plotting functions (i.e. instead of returning a
Figure)? Or is this an issue with Jupyter (and not Matplotlib)?
Thank you for your help!