voyager
voyager

Reputation: 343

How do you suppress matplotlib output in for loop in Jupyter Notebook?

I am looping over a list of DataFrame column names to create barplots using matplotlib.pyplot in a Jupyter Notebook. Each iteration, I'm using the columns to group the bars. Like so:

%matplotlib inline

import pandas as pd
from matplotlib import pyplot as plt


# Run all output interactively
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"


df = pd.DataFrame({'col1': ['A', 'B', 'C'], 'col2': ['X', 'Y', 'Z'], 'col3': [10, 20, 30]})

#This DOES NOT suppress output
cols_to_plot = ['col1', 'col2']
for col in cols_to_plot:
    fig, ax = plt.subplots()
    ax.bar(df[col], df['col3'])
    plt.show();

The semicolon (';') should suppress text output but when I run the code I get, after the 1st run:

enter image description here

If I run a similar snippet outside of a for loop, it works as expected - the following successfully suppresses output:

# This DOES suppress output
fig, ax = plt.subplots()
ax.bar(df['col1'], df['col3'])
plt.show();

How do I suppress this text output when looping?


Note:

In a previous version of this question, I used the following code to which some of the comments refer, yet I changed it to the above to better show the issue.

cols_to_boxplot = ['country', 'province']
for col in cols_to_boxplot:
    fig, ax = plt.subplots(figsize = (15, 10))
    sns.boxplot(y=wine['log_price'], x=wine[col])
    labels = ax.get_xticklabels()
    ax.set_xticklabels(labels, rotation=90);
    ax.set_title('log_price vs {0}'.format(col))
    plt.show();

Upvotes: 4

Views: 2421

Answers (3)

Dominic van der Pas
Dominic van der Pas

Reputation: 142

Try replacing plt.show() with plt.close().

It worked for me.

Upvotes: 0

Arend
Arend

Reputation: 333

@voyager's answer worked for me, but only if I put

InteractiveShell.ast_node_interactivity = "last_expr"

in the cell preceding the cell with the matplotlib annotate loop.

Alternative: I wrapped the plot code containing the annotate loop into a plot function. If you call this function, the repeated 'Text' output remains within the function, no longer requiring a change to the InteractiveShell settings:

def plot_with_loop(df):
   ...
   ax = df.plot();

   for i in range(len(df)):
        # next line generates 'Text' output when not called contained in function
        ax.annotate(...); 
    

plot_with_loop(df)  # no 'Text' output

Upvotes: 0

voyager
voyager

Reputation: 343

I discovered what what causing this behaviour. I ran my notebook with the following:

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

(documented here)

This had the effect of not suppressing matplotlib output when plotting in a loop. However, as mentioned in the original post, it did suppress output as expected when not within a loop. In any case, I fixed the issue by 'undoing' my code above like this:

InteractiveShell.ast_node_interactivity = "last_expr"

I'm not sure why this would happen.

Upvotes: 7

Related Questions