matplotlib icon indicating copy to clipboard operation
matplotlib copied to clipboard

[Bug]: mpl.style.context() stops plotting inline in Jupyter

Open iainAtIon opened this issue 2 years ago • 5 comments

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: image

CASE 2: image

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

iainAtIon avatar Sep 07 '23 14:09 iainAtIon

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'

tacaswell avatar Sep 08 '23 21:09 tacaswell

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...

iainAtIon avatar Sep 11 '23 10:09 iainAtIon

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.

kamunwasam avatar Nov 20 '23 09:11 kamunwasam

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.

iainAtIon avatar Nov 22 '23 10:11 iainAtIon

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.

tzeitim avatar Feb 03 '24 14:02 tzeitim