AxesSubplot not rendered after plot() in another cell

Viewed 178

I plot some data from pandas DataFrame in a Jupyter notebook cell like this:

    ax = data.plot('Weight', 'Height', kind='scatter', backend='matplotlib')
    print(type(ax))
    ax.plot(xs, line1, color='red')
    print(type(ax))
    ax.plot(xs, line2, color='yellow')
    print(type(ax))

I see that ax is of the type <class 'matplotlib.axes._subplots.AxesSubplot'>. All good.

Then, in the next cell, I am trying to plot another line, reusing ax, just like I did with ax.plot(xs, line2, color='yellow'):

ax.plot(w1_arr, errors, color='red')
print(type(ax)) 

However, nothing is rendered, except for the type of ax, it is the same <class 'matplotlib.axes._subplots.AxesSubplot'>.

Questions:

  1. Why is nothing rendered? Is it because within a single Jupyter cell it is fine to 'reuse' ax because it reads all of the commands to plot, and then plot everything at once? But it is not fine to try to 'reuse' ax outside that single cell?
  2. Why is the type of ax AxesSubplot and not simply Axes? As per DataFrame.plot(), it should return Axes, I have explicitly set backend='matplotlib'.
1 Answers

By fiddling around I found a way to make it work, but I am researching it as well it is an interesting behaviour ad I also do not fully understand it atm.

My feeling is that it has to do with how artist and renderer are stored and persisted in the Figure or Axes classes and across jupyter cells.

The following snippet will work:

############################ CELL 1 ################################
import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame({'a': np.random.randint(0,30,10), 'b': np.random.randint(0,30,10)})

fig, ax = plt.subplots()
df.plot('a', 'b', kind='scatter', backend='matplotlib', ax=ax)
ax.plot(np.arange(0,30,10), np.arange(0,30,10), color='red')
ax.plot(np.arange(0,30,10), np.arange(0,30,10)+5, color='yellow')

############################ CELL 2 ################################
ax.plot(np.arange(0,30,10), np.arange(0,30,10)+15, color='blue')
fig

In addition, the behaviour you observed must also be related to the inline rendering of jupyter. If you us qt instead by %matplotlib qt, which will create an external figure, the code you posted will work fine, like such:

############################ CELL 1 ################################
import pandas as pd
import matplotlib.pyplot as plt

%matplotlib qt

df = pd.DataFrame({'a': np.random.randint(0,30,10), 'b': np.random.randint(0,30,10)})

ax = df.plot('a', 'b', kind='scatter', backend='matplotlib')
ax.plot(np.arange(0,30,10), np.arange(0,30,10), color='red')
ax.plot(np.arange(0,30,10), np.arange(0,30,10)+5, color='yellow')

############################ CELL 2 ################################
# minimize the figure that popped up and run the second cell
ax.plot(np.arange(0,30,10), np.arange(0,30,10)+15, color='blue')

If you find the rationale behind it please post it, I and maybe others would be interested.

Related