[Bug]: mpl.style.context() stops plotting inline in Jupyter
Bug summary
Under certain circumstances, when using matplotlib.style.context() to temporarily alter the default style in a Jupyter notebook, it resets the backend to no plot inline. This occurs if the plot is the first one in the notebook, but not if another plot (without the context manager) has already been plotted.
Code for reproduction
# CASE 1:
# first cell - produces inline plot with desired grid
import matplotlibl.pyplot as pl
with plt.style.context({'axes.grid': True}):
plt.plot(range(10))
# second cell - does not produce in line plot
plt.plot(range(10))
# CASE 2:
# first cell - produces inline plot
import matplotlibl.pyplot as plt
plt.plot(range(10))
# second cell - produces inline plot with desired grid
with plt.style.context({'axes.grid': True}):
plt.plot(range(10))
# third cell - produces in line plot
plt.plot(range(10))
Actual outcome
CASE 1:
CASE 2:
Expected outcome
In case 1, the second plot should be inline
Additional information
No response
Operating system
Windows 10.0.19045 Build 19045
Matplotlib Version
3.7.2
Matplotlib Backend
'module://matplotlib_inline.backend_inline'
Python version
3.10.10
Jupyter version
6.4.12
Installation
pip
This looks like another instance of a backend setting rcparams on import (which we now defer until we actually need to render a figure) and then the context manager resets it.
In this case it looks like it is 'interactive'. In the short term, calling plt.ion() at anypoint should fix the problem.
Medium term we should condsider excluding 'interactive' from rc_context the same way we exclude 'backend'
Hi Thomas, thanks for looking at this. So does the issue really lie with the matplotlib-inline package rather than matplotlib itself? Is this something which needs to be/can be fixed? Or intended behaviour?
In the meantime I can confirm that both solutions you proposed work. Although neither are ideal - running plt.ion() is an extra line of code I'll have to run across any notebook I work with. And editing the matplotlib source files isn't ideal either...
It appears that using matplotlib.style.context() to temporarily change the default style in a Jupyter notebook might affect the backend for subsequent plots in certain situations. Specifically, when the first plot is created within a context manager that alters the default style, it can lead to subsequent plots not being displayed inline.
This behavior seems to stem from the interaction between the context manager and the backend setup in Jupyter notebooks. To resolve this issue, you might consider explicitly specifying the backend and applying the style within the same cell for consistent inline plotting:
import matplotlib.pyplot as plt
# Explicitly set the backend
%matplotlib inline
# Apply the style and plot
with plt.style.context({'axes.grid': True}):
plt.plot(range(10))
# Subsequent plots
plt.plot(range(10)) # Should display inline
By setting the backend explicitly before any plotting commands and applying the style within the same cell as the plot command, it should ensure consistent inline plotting without being affected by the context manager's behavior in subsequent cells. This way, the default style is set, and subsequent plots should display inline as expected.
Hi Sam, I can confirm the above works. However, this doesn't feel like a completely satisfactory solution as it relies on the user having to remember to set %matplotlib inline in every notebook. Since inline plotting is default behaviour in current jupyter versions, this is not ideal. Additionally, I have use cases where the matplotlib.style.context() manager is used on imported functions, so its use is hidden from the end user, making this bug difficult to spot.
I had the same problem. It took me a long time to figure out why things would stop working sometimes. In my humble opinion the workaround suggested above is a bit cumbersome.