PyplotGlobalUseWarning

Hello.
Iā€™m using seaborn to plot a chart. The code works fine. But, I`m getting this warning:

**PyplotGlobalUseWarning** : You are calling  `st.pyplot()`  without any arguments. After December 
 1st, 2020, we will remove the ability to do this as it requires the use of Matplotlib's global figure 
 object, which is not thread-safe.

Iā€™ve been looking for some answers. But I could find it.
Iā€™m following the instruction, but Iā€™m donā€™t know what is wrong.

How can I figure it out?

Many thanks.

Hi @Racchel, welcome to the Streamlit community!

That warning is telling you to put your plot object as an argument in st.pyplot. What does your code look like right now thatā€™s throwing the warning?

Hi @randyzwitch.

Here is my code:

fig, ax = plt.figure(figsize=(15,5))
ax = (sns.lineplot(x="DIAS_RESTANTES_PARA_VIAGEM", y="min", data=df_voos_originais, ci=None, palette="muted", label='min'),
sns.lineplot(x="DIAS_RESTANTES_PARA_VIAGEM", y="max", data=df, ci=None, palette="muted", label='max'),
plt.title(titulo, fontweight="bold", fontsize=16, pad=20),
plt.ylabel('Cost'))
st.pyplot(fig)

Iā€™m following the instruction, but Iā€™m donā€™t know what is wrong.
I tried that code as mentioned st.set_option('deprecation.showPyplotGlobalUse', False) . But Iā€™m still getting that warning.

For some reason this line is working: st.set_option('deprecation.showPyplotGlobalUse', False)

Hey @Racchel. I might be able to help suppress the error without setting that option. If you feel itā€™s okay to suppress the deprecation warning, thatā€™s fine. However, itā€™s possible we can change the script and undo the suppression.

Like @randyzwitch says, the warning pops up because an argument is not being sent to st.pyplot. When the argument isnā€™t specified, we internally call plt.savefig rather than on the figure itself. This works so long as you are looking at the graph on a single browser tab. No other tabs should be open on that page, and, if deployed online, multiple people will not be able to access it at the same time.

I tried the code you provided, but an error appears unrelated.

>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.figure(figsize=(15,5))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: cannot unpack non-iterable Figure object

I think to fix this we need to use the plt.subplots command.

fig, ax = plt.subplots()
# ...
st.pyplot(fig)

Using plt.subplots(), we now need to do operations on ax instead of plt. For seaborn, most plotting have an ax command to perform the operations on (instead of plt). Lastly, thereā€™s a slight change in setting the title and y_label.

I canā€™t test this code because I do not have the data, but I think the following changes will work. Note the use of ax in each line.

fig, ax = plt.subplots(figsize=(15,5))

# Seaborn Operations (Note ax=ax)
sns.lineplot(x="DIAS_RESTANTES_PARA_VIAGEM", y="min", data=df_voos_originais, ci=None, palette="muted", label='min', ax=ax)
sns.lineplot(x="DIAS_RESTANTES_PARA_VIAGEM", y="max", data=df, ci=None, palette="muted", label='max', ax=ax)

# See Operations on Axes https://matplotlib.org/3.1.1/api/axes_api.html
ax.set_title(titulo, fontweight="bold", fontsize=16, pad=20),
ax.set_ylabel('Cost'))

# Now we can send the fig to pyplot
st.pyplot(fig)

If the above works, then you should be able to remove st.set_option('deprecation.showPyplotGlobalUse', False) Andā€¦fingers crossedā€¦no warning should appear!

I hope that helps!

Hi @kmcgrady.

Thanks for your time and a great explanation.
Everything is working.

Once again, many thanks.

hello,
i have same issue in my code :slight_smile:
PyplotGlobalUseWarning : You are calling st.pyplot() without any arguments. After December 1st, 2020, we will remove the ability to do this as it requires the use of Matplotlibā€™s global figure object, which is not thread-safe.

code

import streamlit as st

import pandas as pd

import shap

import matplotlib.pyplot as plt

from sklearn import datasets

from sklearn.ensemble import RandomForestRegressor

st.write("""

# Boston House Price Prediction App

This app predicts the **Boston House Price**!

""")

st.write('---')

# Loads the Boston House Price Dataset

boston = datasets.load_boston()

X = pd.DataFrame(boston.data, columns=boston.feature_names)

Y = pd.DataFrame(boston.target, columns=["MEDV"])

# Sidebar

# Header of Specify Input Parameters

st.sidebar.header('Specify Input Parameters')

def user_input_features():

    CRIM = st.sidebar.slider('CRIM', X.CRIM.min(), X.CRIM.max(), X.CRIM.mean())

    ZN = st.sidebar.slider('ZN', X.ZN.min(), X.ZN.max(), X.ZN.mean())

    INDUS = st.sidebar.slider('INDUS', X.INDUS.min(), X.INDUS.max(), X.INDUS.mean())

    CHAS = st.sidebar.slider('CHAS', X.CHAS.min(), X.CHAS.max(), X.CHAS.mean())

    NOX = st.sidebar.slider('NOX', X.NOX.min(), X.NOX.max(), X.NOX.mean())

    RM = st.sidebar.slider('RM', X.RM.min(), X.RM.max(), X.RM.mean())

    AGE = st.sidebar.slider('AGE', X.AGE.min(), X.AGE.max(), X.AGE.mean())

    DIS = st.sidebar.slider('DIS', X.DIS.min(), X.DIS.max(), X.DIS.mean())

    RAD = st.sidebar.slider('RAD', X.RAD.min(), X.RAD.max(), X.RAD.mean())

    TAX = st.sidebar.slider('TAX', X.TAX.min(), X.TAX.max(), X.TAX.mean())

    PTRATIO = st.sidebar.slider('PTRATIO', X.PTRATIO.min(), X.PTRATIO.max(), X.PTRATIO.mean())

    B = st.sidebar.slider('B', X.B.min(), X.B.max(), X.B.mean())

    LSTAT = st.sidebar.slider('LSTAT', X.LSTAT.min(), X.LSTAT.max(), X.LSTAT.mean())

    data = {'CRIM': CRIM,

            'ZN': ZN,

            'INDUS': INDUS,

            'CHAS': CHAS,

            'NOX': NOX,

            'RM': RM,

            'AGE': AGE,

            'DIS': DIS,

            'RAD': RAD,

            'TAX': TAX,

            'PTRATIO': PTRATIO,

            'B': B,

            'LSTAT': LSTAT}

    features = pd.DataFrame(data, index=[0])

    return features

df = user_input_features()

# Main Panel

# Print specified input parameters

st.header('Specified Input parameters')

st.write(df)

st.write('---')

# Build Regression Model

model = RandomForestRegressor()

model.fit(X, Y)

# Apply Model to Make Prediction

prediction = model.predict(df)

st.header('Prediction of MEDV')

st.write(prediction)

st.write('---')

# Explaining the model's predictions using SHAP values

# https://github.com/slundberg/shap

explainer = shap.TreeExplainer(model)

shap_values = explainer.shap_values(X)

st.header('Feature Importance')

plt.title('Feature importance based on SHAP values')

shap.summary_plot(shap_values, X)

st.pyplot(bbox_inches='tight')

st.write('---')

plt.title('Feature importance based on SHAP values (Bar)')

shap.summary_plot(shap_values, X, plot_type="bar")

st.pyplot(bbox_inches='tight')

Hi @hamiz_khan, welcome to the Streamlit community!

These lines are the type of code that Streamlit is warning you about:

st.pyplot(bbox_inches='tight')

Youā€™re calling pyplot without passing an object in, which isnā€™t thread-safe. As PyplotGlobalUseWarning - #5 by kmcgrady indicates, you can either pass in a chart object or disable the warning via Streamlit configuration. Though, do note that eventually, the syntax will get deprecated to remove the thread-safety issue, so changing your configuration is a temporary solution.

Best,
Randy